From c0986a07fc59f496f46866f0c2b5f0764632482a Mon Sep 17 00:00:00 2001 From: Axel Date: Wed, 20 Jan 2021 13:31:53 +0100 Subject: [PATCH] Improved movement components vehicle interface. --- .../Carla/Source/Carla/Server/CarlaServer.cpp | 34 +-- .../Source/Carla/Util/EnvironmentObject.h | 2 + .../Carla/Vehicle/CarlaWheeledVehicle.cpp | 247 +----------------- .../Carla/Vehicle/CarlaWheeledVehicle.h | 67 +---- .../BaseCarlaMovementComponent.cpp | 47 ++++ .../BaseCarlaMovementComponent.h | 36 +++ .../CarSimManagerComponent.cpp | 171 ++++++++++++ .../CarSimManagerComponent.h | 72 +++++ .../DefaultMovementComponent.cpp | 55 ++++ .../DefaultMovementComponent.h | 34 +++ 10 files changed, 462 insertions(+), 303 deletions(-) create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/BaseCarlaMovementComponent.cpp create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/BaseCarlaMovementComponent.h create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/CarSimManagerComponent.cpp create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/CarSimManagerComponent.h create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/DefaultMovementComponent.cpp create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/DefaultMovementComponent.h diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp index ae07bfcba..5de6e6164 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp @@ -16,6 +16,7 @@ #include "Carla/Walker/WalkerBase.h" #include "GameFramework/CharacterMovementComponent.h" #include "Carla/Game/Tagger.h" +#include "Carla/Vehicle/MovementComponents/CarSimManagerComponent.h" #include #include @@ -919,7 +920,11 @@ void FCarlaServer::FPimpl::BindActions() auto* CarlaVehicle = Cast(ActorView.GetActor()); // The physics in the vehicles works in a different way so to disable them. if (CarlaVehicle != nullptr){ - CarlaVehicle->SetSimulatePhysics(bEnabled); + // Ignore the call for carsim + if (!CarlaVehicle->GetCarlaMovementComponent()) + { + CarlaVehicle->SetSimulatePhysics(bEnabled); + } } // The physics in the walkers also works in a different way so to disable them, // we need to do it in the UCharacterMovementComponent. @@ -1085,12 +1090,10 @@ void FCarlaServer::FPimpl::BindActions() return R::Success(); }; -//-----CARSIM-------------------------------- BIND_SYNC(enable_carsim) << [this]( cr::ActorId ActorId, std::string SimfilePath) -> R { - #ifdef WITH_CARSIM REQUIRE_CARLA_EPISODE(); auto ActorView = Episode->FindActor(ActorId); if (!ActorView.IsValid()) @@ -1102,22 +1105,14 @@ void FCarlaServer::FPimpl::BindActions() { RESPOND_ERROR("unable to set carsim: not actor is not a vehicle"); } - if (Vehicle->IsCarSimEnabled()) - { - RESPOND_ERROR("unable to set carsim: carsim is already enabled"); - } - Vehicle->EnableCarSim(carla::rpc::ToFString(SimfilePath)); + UCarSimManagerComponent::CreateCarsimComponent(Vehicle, carla::rpc::ToFString(SimfilePath)); return R::Success(); - #else - RESPOND_ERROR("CarSim plugin is not enabled"); - #endif }; BIND_SYNC(use_carsim_road) << [this]( cr::ActorId ActorId, bool bEnabled) -> R { - #ifdef WITH_CARSIM REQUIRE_CARLA_EPISODE(); auto ActorView = Episode->FindActor(ActorId); if (!ActorView.IsValid()) @@ -1129,13 +1124,18 @@ void FCarlaServer::FPimpl::BindActions() { RESPOND_ERROR("unable to set carsim road: not actor is not a vehicle"); } - Vehicle->UseCarSimRoad(bEnabled); + auto* CarSimComponent = Vehicle->GetCarlaMovementComponent(); + if(CarSimComponent) + { + CarSimComponent->UseCarSimRoad(bEnabled); + } + else + { + RESPOND_ERROR("UCarSimManagerComponent plugin is not activated"); + } return R::Success(); - #else - RESPOND_ERROR("CarSim plugin is not enabled"); - #endif }; -//-----CARSIM-------------------------------- + // ~~ Traffic lights ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BIND_SYNC(set_traffic_light_state) << [this]( diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/EnvironmentObject.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/EnvironmentObject.h index b5a79dfcd..25bf1708c 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/EnvironmentObject.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/EnvironmentObject.h @@ -9,6 +9,8 @@ #include #include +#include "BoundingBox.h" + #include "EnvironmentObject.generated.h" namespace crp = carla::rpc; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp index 7ecbe845a..d7367be64 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp @@ -17,6 +17,7 @@ #include "VehicleWheel.h" #include "Carla/Util/ActorAttacher.h" #include "Carla/Util/EmptyActor.h" +#include "MovementComponents/DefaultMovementComponent.h" #include "Rendering/SkeletalMeshRenderData.h" @@ -35,13 +36,9 @@ ACarlaWheeledVehicle::ACarlaWheeledVehicle(const FObjectInitializer& ObjectIniti VelocityControl = CreateDefaultSubobject(TEXT("VelocityControl")); VelocityControl->Deactivate(); - #ifdef WITH_CARSIM - // ExternalMovementComponent = CreateDefaultSubobject(TEXT("CarSimMovement")); - // CarSimMovementComponent = Cast(ExternalMovementComponent); - // CarSimMovementComponent->DisableVehicle = true; - #endif - GetVehicleMovementComponent()->bReverseAsBrake = false; + + BaseMovementComponent = CreateDefaultSubobject(TEXT("BaseMovementComponent")); } ACarlaWheeledVehicle::~ACarlaWheeledVehicle() {} @@ -76,6 +73,8 @@ void ACarlaWheeledVehicle::BeginPlay() { Super::BeginPlay(); + UDefaultMovementComponent::CreateDefaultMovementComponent(this); + float FrictionScale = 3.5f; UWheeledVehicleMovementComponent4W *Vehicle4W = Cast( @@ -148,13 +147,7 @@ void ACarlaWheeledVehicle::AdjustVehicleBounds() float ACarlaWheeledVehicle::GetVehicleForwardSpeed() const { - #ifdef WITH_CARSIM - if (bCarSimEnabled) - { - return CarSimMovementComponent->GetForwardSpeed(); - } - #endif - return GetVehicleMovementComponent()->GetForwardSpeed(); + return BaseMovementComponent->GetVehicleForwardSpeed(); } FVector ACarlaWheeledVehicle::GetVehicleOrientation() const @@ -164,13 +157,7 @@ FVector ACarlaWheeledVehicle::GetVehicleOrientation() const int32 ACarlaWheeledVehicle::GetVehicleCurrentGear() const { - #ifdef WITH_CARSIM - if (bCarSimEnabled) - { - return CarSimMovementComponent->GetCurrentGear(); - } - #endif - return GetVehicleMovementComponent()->GetCurrentGear(); + return BaseMovementComponent->GetVehicleCurrentGear(); } FTransform ACarlaWheeledVehicle::GetVehicleBoundingBoxTransform() const @@ -198,57 +185,7 @@ float ACarlaWheeledVehicle::GetMaximumSteerAngle() const void ACarlaWheeledVehicle::FlushVehicleControl() { - #ifdef WITH_CARSIM - if (bCarSimEnabled) - { - //-----CARSIM-------------------------------- - CarSimMovementComponent->SetThrottleInput(InputControl.Control.Throttle); - CarSimMovementComponent->SetSteeringInput(InputControl.Control.Steer); - CarSimMovementComponent->SetBrakeInput(InputControl.Control.Brake); - if (InputControl.Control.bHandBrake) - { - CarSimMovementComponent->SetBrakeInput(InputControl.Control.Brake + 1.0); - } - // CarSimMovementComponent->SetHandbrakeInput(InputControl.Control.bHandBrake); - // if (LastAppliedControl.bReverse != InputControl.Control.bReverse) - // { - // CarSimMovementComponent->SetUseAutoGears(!InputControl.Control.bReverse); - // CarSimMovementComponent->SetTargetGear(InputControl.Control.bReverse ? -1 : 1, true); - // } - // else - // { - // CarSimMovementComponent->SetUseAutoGears(!InputControl.Control.bManualGearShift); - // if (InputControl.Control.bManualGearShift) - // { - // CarSimMovementComponent->SetTargetGear(InputControl.Control.Gear, true); - // } - // } - InputControl.Control.Gear = CarSimMovementComponent->GetCurrentGear(); - //----------------------------------------- - } - else - #endif - { - auto *MovementComponent = GetVehicleMovementComponent(); - MovementComponent->SetThrottleInput(InputControl.Control.Throttle); - MovementComponent->SetSteeringInput(InputControl.Control.Steer); - MovementComponent->SetBrakeInput(InputControl.Control.Brake); - MovementComponent->SetHandbrakeInput(InputControl.Control.bHandBrake); - if (LastAppliedControl.bReverse != InputControl.Control.bReverse) - { - MovementComponent->SetUseAutoGears(!InputControl.Control.bReverse); - MovementComponent->SetTargetGear(InputControl.Control.bReverse ? -1 : 1, true); - } - else - { - MovementComponent->SetUseAutoGears(!InputControl.Control.bManualGearShift); - if (InputControl.Control.bManualGearShift) - { - MovementComponent->SetTargetGear(InputControl.Control.Gear, true); - } - } - InputControl.Control.Gear = MovementComponent->GetCurrentGear(); - } + BaseMovementComponent->ProcessControl(InputControl.Control); InputControl.Control.bReverse = InputControl.Control.Gear < 0; LastAppliedControl = InputControl.Control; InputControl.Priority = EVehicleInputPriority::INVALID; @@ -507,132 +444,13 @@ void ACarlaWheeledVehicle::SetVehicleLightState(const FVehicleLightState &LightS RefreshLightState(LightState); } -//-----CARSIM-------------------------------- -void ACarlaWheeledVehicle::OnCarSimHit(AActor *Actor, - AActor *OtherActor, - FVector NormalImpulse, - const FHitResult &Hit) +void ACarlaWheeledVehicle::SetCarlaMovementComponent(UBaseCarlaMovementComponent* MovementComponent) { - // handle collision forces here -} - - -void ACarlaWheeledVehicle::OnCarSimOverlap(UPrimitiveComponent* OverlappedComponent, - AActor* OtherActor, - UPrimitiveComponent* OtherComp, - int32 OtherBodyIndex, - bool bFromSweep, - const FHitResult & SweepResult) -{ - if (OtherComp->GetCollisionResponseToChannel( - ECollisionChannel::ECC_WorldDynamic) == - ECollisionResponse::ECR_Block) + if (BaseMovementComponent) { - // handle collision forces here + BaseMovementComponent->DestroyComponent(); } -} - -void ACarlaWheeledVehicle::SwitchToUE4Physics() -{ - #ifdef WITH_CARSIM - GetMesh()->SetPhysicsLinearVelocity(FVector(0,0,0), false, "Vehicle_Base"); - GetVehicleMovementComponent()->SetComponentTickEnabled(true); - GetVehicleMovementComponent()->Activate(); - CarSimMovementComponent->DisableVehicle = true; - CarSimMovementComponent->SetComponentTickEnabled(false); - CarSimMovementComponent->Deactivate(); - CarSimMovementComponent->VsConfigFile = ""; - GetMesh()->PhysicsTransformUpdateMode = EPhysicsTransformUpdateMode::SimulationUpatesComponentTransform; - auto * Bone = GetMesh()->GetBodyInstance(NAME_None); - if (Bone) - { - Bone->SetInstanceSimulatePhysics(true); - } - else - { - carla::log_warning("No bone with name"); - } - OnActorHit.RemoveDynamic(this, &ACarlaWheeledVehicle::OnCarSimHit); - GetMesh()->OnComponentBeginOverlap.RemoveDynamic(this, &ACarlaWheeledVehicle::OnCarSimOverlap); - GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block); - GetMesh()->SetCollisionProfileName("Vehicle"); - carla::log_warning("There was a hit"); - #endif -} - -void ACarlaWheeledVehicle::RevertToCarSimPhysics() -{ - #ifdef WITH_CARSIM - GetVehicleMovementComponent()->SetComponentTickEnabled(false); - GetVehicleMovementComponent()->Deactivate(); - CarSimMovementComponent->DisableVehicle = false; - CarSimMovementComponent->Activate(); - // CarSimMovementComponent->ResetVsVehicle(false); - // set carsim position to actor's - CarSimMovementComponent->SyncVsVehicleLocOri(); - CarSimMovementComponent->SetComponentTickEnabled(true); - // set kinematic mode for root component and bones - GetMesh()->PhysicsTransformUpdateMode = EPhysicsTransformUpdateMode::ComponentTransformIsKinematic; - auto * Bone = GetMesh()->GetBodyInstance(NAME_None); - if (Bone) - { - Bone->SetInstanceSimulatePhysics(false); - } - // set callbacks to react to collisions - OnActorHit.AddDynamic(this, &ACarlaWheeledVehicle::OnCarSimHit); - GetMesh()->OnComponentBeginOverlap.AddDynamic(this, &ACarlaWheeledVehicle::OnCarSimOverlap); - GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Overlap); - carla::log_warning("Collision: giving control to carsim"); - #endif -} - -void ACarlaWheeledVehicle::EnableCarSim(FString SimfilePath) -{ - #ifdef WITH_CARSIM - // workarround to compensate carsim coordinate origin offset - FActorSpawnParameters SpawnParams; - SpawnParams.SpawnCollisionHandlingOverride = - ESpawnActorCollisionHandlingMethod::AlwaysSpawn; - OffsetActor = GetWorld()->SpawnActor( - GetActorLocation() + GetActorForwardVector() * CarSimOriginOffset, - GetActorRotation(), - SpawnParams); - CarSimMovementComponent = NewObject(OffsetActor); - - // CarSimMovementComponent = NewObject(this); - // ExternalMovementComponent = CarSimMovementComponent; - carla::log_warning("Loading simfile:", carla::rpc::FromFString(SimfilePath)); - GetVehicleMovementComponent()->SetComponentTickEnabled(false); - GetVehicleMovementComponent()->Deactivate(); - CarSimMovementComponent->DisableVehicle = false; - CarSimMovementComponent->VsConfigFile = SimfilePath; - CarSimMovementComponent->Activate(); - CarSimMovementComponent->RegisterComponent(); - - CarSimMovementComponent->ResetVsVehicle(false); - // set carsim position to actor's - CarSimMovementComponent->SyncVsVehicleLocOri(); - CarSimMovementComponent->SetComponentTickEnabled(true); - // set kinematic mode for root component and bones - GetMesh()->PhysicsTransformUpdateMode = EPhysicsTransformUpdateMode::ComponentTransformIsKinematic; - auto * Bone = GetMesh()->GetBodyInstance(NAME_None); - if (Bone) - { - Bone->SetInstanceSimulatePhysics(false); - } - // set callbacks to react to collisions - OnActorHit.AddDynamic(this, &ACarlaWheeledVehicle::OnCarSimHit); - GetMesh()->OnComponentBeginOverlap.AddDynamic(this, &ACarlaWheeledVehicle::OnCarSimOverlap); - GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Overlap); - - // workaround to prevent carsim from interacting with its own car - GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Visibility, ECollisionResponse::ECR_Overlap); - - // attach to actor with an offset - AttachToActor(OffsetActor, FAttachmentTransformRules::KeepWorldTransform); - - bCarSimEnabled = true; - #endif + BaseMovementComponent = MovementComponent; } void ACarlaWheeledVehicle::SetSimulatePhysics(bool enabled) { @@ -644,9 +462,7 @@ void ACarlaWheeledVehicle::SetSimulatePhysics(bool enabled) { return; SetActorEnableCollision(true); - #ifdef WITH_CARSIM - if(!IsCarSimEnabled()) - #endif + if(!GetCarlaMovementComponent()) { auto RootComponent = Cast(GetRootComponent()); RootComponent->SetSimulatePhysics(enabled); @@ -663,42 +479,7 @@ void ACarlaWheeledVehicle::SetSimulatePhysics(bool enabled) { bPhysicsEnabled = enabled; } -void ACarlaWheeledVehicle::UseCarSimRoad(bool bEnabled) -{ - #ifdef WITH_CARSIM - carla::log_warning("Enabling CarSim Road", bEnabled); - CarSimMovementComponent->UseVehicleSimRoad = bEnabled; - CarSimMovementComponent->ResetVsVehicle(false); - CarSimMovementComponent->SyncVsVehicleLocOri(); - #endif -} - -#ifdef WITH_CARSIM FVector ACarlaWheeledVehicle::GetVelocity() const { - if (bCarSimEnabled) - { - return GetActorForwardVector() * CarSimMovementComponent->GetForwardSpeed(); - } - else - { - return Super::GetVelocity(); - } + return BaseMovementComponent->GetVelocity(); } -#endif - -bool ACarlaWheeledVehicle::IsCarSimEnabled() const -{ - return bCarSimEnabled; -} - -void ACarlaWheeledVehicle::EndPlay(const EEndPlayReason::Type EndPlayReason) -{ - #ifdef WITH_CARSIM - if (OffsetActor) - { - OffsetActor->Destroy(); - } - #endif -} -//------------------------------------------- diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h index 8bf7a7b3f..c07e6742e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h @@ -15,6 +15,7 @@ #include "Vehicle/VehiclePhysicsControl.h" #include "VehicleVelocityControl.h" #include "WheeledVehicleMovementComponent4W.h" +#include "MovementComponents/BaseCarlaMovementComponent.h" #include "CoreMinimal.h" @@ -206,6 +207,14 @@ public: void SetWheelsFrictionScale(TArray &WheelsFrictionScale); + void SetCarlaMovementComponent(UBaseCarlaMovementComponent* MoementComponent); + + template + T* GetCarlaMovementComponent() const + { + return Cast(BaseMovementComponent); + } + /// @} // =========================================================================== /// @name Overriden from AActor @@ -244,70 +253,22 @@ private: FVehicleControl LastAppliedControl; - -//-----CARSIM-------------------------------- public: - // Enables carsim once enabled it won't turn back to UE4 physics simulation - // (for some reason the UE4 physics get meesed up after enabling carsim) - UFUNCTION(Category="CARLA Wheeled Vehicle", BlueprintCallable) - void EnableCarSim(FString SimfilePath = ""); - - // Enables usage of carsim terrain - UFUNCTION(Category="CARLA Wheeled Vehicle", BlueprintCallable) - void UseCarSimRoad(bool bEnabled); - - #ifdef WITH_CARSIM virtual FVector GetVelocity() const override; - #endif - - UFUNCTION(Category="CARLA Wheeled Vehicle", BlueprintPure) - bool IsCarSimEnabled() const; - - virtual void EndPlay(const EEndPlayReason::Type EndPlayReason); - -private: - - // On car mesh hit, only works when carsim is enabled - UFUNCTION() - void OnCarSimHit(AActor *Actor, - AActor *OtherActor, - FVector NormalImpulse, - const FHitResult &Hit); - - // On car mesh overlap, only works when carsim is enabled - // (this event triggers when overlapping with static environment) - UFUNCTION() - void OnCarSimOverlap(UPrimitiveComponent* OverlappedComponent, - AActor* OtherActor, - UPrimitiveComponent* OtherComp, - int32 OtherBodyIndex, - bool bFromSweep, - const FHitResult & SweepResult); - - UFUNCTION() - void SwitchToUE4Physics(); - - UFUNCTION() - void RevertToCarSimPhysics(); - - UPROPERTY(Category="CARLA Wheeled Vehicle", VisibleAnywhere) - bool bCarSimEnabled = false; +//-----CARSIM-------------------------------- UPROPERTY(Category="CARLA Wheeled Vehicle", EditAnywhere) float CarSimOriginOffset = 150.f; +//------------------------------------------- +private: UPROPERTY(Category="CARLA Wheeled Vehicle", VisibleAnywhere) bool bPhysicsEnabled = true; // Small workarround to allow optional CarSim plugin usage UPROPERTY(Category="CARLA Wheeled Vehicle", VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) - UMovementComponent * ExternalMovementComponent; + UBaseCarlaMovementComponent * BaseMovementComponent = nullptr; + - #ifdef WITH_CARSIM - AActor* OffsetActor; - // Casted version of ExternalMovementComponent - UCarSimMovementComponent * CarSimMovementComponent; - #endif - //------------------------------------------- }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/BaseCarlaMovementComponent.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/BaseCarlaMovementComponent.cpp new file mode 100644 index 000000000..ca949adc9 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/BaseCarlaMovementComponent.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma +// de Barcelona (UAB). +// Copyright (c) 2019 Intel Corporation +// +// This work is licensed under the terms of the MIT license. +// For a copy, see . + +#include "BaseCarlaMovementComponent.h" +#include "Carla/Vehicle/CarlaWheeledVehicle.h" + +void UBaseCarlaMovementComponent::BeginPlay() +{ + Super::BeginPlay(); + ACarlaWheeledVehicle* Vehicle = Cast(GetOwner()); + if (Vehicle) + { + CarlaVehicle = Vehicle; + } + else + { + UE_LOG(LogCarla, Warning, TEXT("Error: Owner is not properly set for UBaseCarlaMovementComponent") ); + } +} + +void UBaseCarlaMovementComponent::ProcessControl(FVehicleControl &Control) +{ + +} + +FVector UBaseCarlaMovementComponent::GetVelocity() const +{ + if (CarlaVehicle) + { + return CarlaVehicle->AWheeledVehicle::GetVelocity(); + } + return FVector(); +} + +int32 UBaseCarlaMovementComponent::GetVehicleCurrentGear() const +{ + return 0; +} + +float UBaseCarlaMovementComponent::GetVehicleForwardSpeed() const +{ + return 0.f; +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/BaseCarlaMovementComponent.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/BaseCarlaMovementComponent.h new file mode 100644 index 000000000..5077061b7 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/BaseCarlaMovementComponent.h @@ -0,0 +1,36 @@ +// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma +// de Barcelona (UAB). +// Copyright (c) 2019 Intel Corporation +// +// This work is licensed under the terms of the MIT license. +// For a copy, see . + +#pragma once + +#include "GameFramework/MovementComponent.h" +#include "Carla/Vehicle/VehicleControl.h" +#include "BaseCarlaMovementComponent.generated.h" + +class ACarlaWheeledVehicle; + +UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent)) +class CARLA_API UBaseCarlaMovementComponent : public UMovementComponent +{ + GENERATED_BODY() + +protected: + + ACarlaWheeledVehicle* CarlaVehicle; + +public: + + virtual void BeginPlay() override; + + virtual void ProcessControl(FVehicleControl &Control); + + virtual FVector GetVelocity() const; + + virtual int32 GetVehicleCurrentGear() const; + + virtual float GetVehicleForwardSpeed() const; +}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/CarSimManagerComponent.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/CarSimManagerComponent.cpp new file mode 100644 index 000000000..8b4025068 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/CarSimManagerComponent.cpp @@ -0,0 +1,171 @@ +// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma +// de Barcelona (UAB). +// Copyright (c) 2019 Intel Corporation +// +// This work is licensed under the terms of the MIT license. +// For a copy, see . + +#include "CarSimManagerComponent.h" +#include "Carla/Vehicle/CarlaWheeledVehicle.h" +#include "Carla/Util/EmptyActor.h" + + +void UCarSimManagerComponent::CreateCarsimComponent( + ACarlaWheeledVehicle* Vehicle, FString Simfile) +{ + #ifdef WITH_CARSIM + UCarSimManagerComponent* CarSimManagerComponent = NewObject(Vehicle); + CarSimManagerComponent->SimfilePath = Simfile; + CarSimManagerComponent->RegisterComponent(); + Vehicle->SetCarlaMovementComponent(CarSimManagerComponent); + #else + UE_LOG(LogCarla, Warning, TEXT("Error: CarSim plugin is not enabled") ); + #endif +} + +void UCarSimManagerComponent::BeginPlay() +{ + Super::BeginPlay(); + #ifdef WITH_CARSIM + + if(!CarlaVehicle) + { + UE_LOG(LogCarla, Warning, TEXT("Error: Owner is not properly set for UCarSimManagerComponent") ); + return; + } + + // workarround to compensate carsim coordinate origin offset + FActorSpawnParameters SpawnParams; + SpawnParams.SpawnCollisionHandlingOverride = + ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + OffsetActor = GetWorld()->SpawnActor( + CarlaVehicle->GetActorLocation() + CarlaVehicle->GetActorForwardVector() * CarlaVehicle->CarSimOriginOffset, + CarlaVehicle->GetActorRotation(), + SpawnParams); + CarSimMovementComponent = NewObject(OffsetActor); + + // CarSimMovementComponent = NewObject(this); + // BaseMovementComponent = CarSimMovementComponent; + carla::log_warning("Loading simfile:", carla::rpc::FromFString(SimfilePath)); + CarlaVehicle->GetVehicleMovementComponent()->SetComponentTickEnabled(false); + CarlaVehicle->GetVehicleMovementComponent()->Deactivate(); + CarSimMovementComponent->DisableVehicle = false; + CarSimMovementComponent->VsConfigFile = SimfilePath; + CarSimMovementComponent->Activate(); + CarSimMovementComponent->RegisterComponent(); + + CarSimMovementComponent->ResetVsVehicle(false); + // set carsim position to actor's + CarSimMovementComponent->SyncVsVehicleLocOri(); + CarSimMovementComponent->SetComponentTickEnabled(true); + // set kinematic mode for root component and bones + CarlaVehicle->GetMesh()->PhysicsTransformUpdateMode = EPhysicsTransformUpdateMode::ComponentTransformIsKinematic; + auto * Bone = CarlaVehicle->GetMesh()->GetBodyInstance(NAME_None); + if (Bone) + { + Bone->SetInstanceSimulatePhysics(false); + } + // set callbacks to react to collisions + CarlaVehicle->OnActorHit.AddDynamic(this, &UCarSimManagerComponent::OnCarSimHit); + CarlaVehicle->GetMesh()->OnComponentBeginOverlap.AddDynamic(this, &UCarSimManagerComponent::OnCarSimOverlap); + CarlaVehicle->GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Overlap); + + // workaround to prevent carsim from interacting with its own car + CarlaVehicle->GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Visibility, ECollisionResponse::ECR_Overlap); + + // attach to actor with an offset + CarlaVehicle->AttachToActor(OffsetActor, FAttachmentTransformRules::KeepWorldTransform); + #else + UE_LOG(LogCarla, Warning, TEXT("Error: CarSim plugin is not enabled") ); + return; + #endif +} + +void UCarSimManagerComponent::ProcessControl(FVehicleControl &Control) +{ + #ifdef WITH_CARSIM + CarSimMovementComponent->SetThrottleInput(Control.Throttle); + CarSimMovementComponent->SetSteeringInput(Control.Steer); + CarSimMovementComponent->SetBrakeInput(Control.Brake); + if (Control.bHandBrake) + { + CarSimMovementComponent->SetBrakeInput(Control.Brake + 1.0); + } + Control.Gear = CarSimMovementComponent->GetCurrentGear(); + #endif +} + +void UCarSimManagerComponent::OnCarSimHit(AActor *Actor, + AActor *OtherActor, + FVector NormalImpulse, + const FHitResult &Hit) +{ + #ifdef WITH_CARSIM + // handle collision forces here + #endif +} + + +void UCarSimManagerComponent::OnCarSimOverlap(UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult & SweepResult) +{ + if (OtherComp->GetCollisionResponseToChannel( + ECollisionChannel::ECC_WorldDynamic) == + ECollisionResponse::ECR_Block) + { + #ifdef WITH_CARSIM + // handle collision forces here + #endif + } +} + +void UCarSimManagerComponent::UseCarSimRoad(bool bEnabled) +{ + #ifdef WITH_CARSIM + CarSimMovementComponent->UseVehicleSimRoad = bEnabled; + CarSimMovementComponent->ResetVsVehicle(false); + CarSimMovementComponent->SyncVsVehicleLocOri(); + #endif +} + + +void UCarSimManagerComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + #ifdef WITH_CARSIM + if (OffsetActor) + { + OffsetActor->Destroy(); + } + #endif +} + +FVector UCarSimManagerComponent::GetVelocity() const +{ + #ifdef WITH_CARSIM + return GetOwner()->GetActorForwardVector() * CarSimMovementComponent->GetForwardSpeed(); + #else + return FVector(); + #endif +} + +int32 UCarSimManagerComponent::GetVehicleCurrentGear() const +{ + #ifdef WITH_CARSIM + return CarSimMovementComponent->GetCurrentGear(); + #else + return 0; + #endif +} + +float UCarSimManagerComponent::GetVehicleForwardSpeed() const +{ + #ifdef WITH_CARSIM + return CarSimMovementComponent->GetForwardSpeed(); + #else + return 0.0; + #endif +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/CarSimManagerComponent.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/CarSimManagerComponent.h new file mode 100644 index 000000000..7fa2a60b5 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/CarSimManagerComponent.h @@ -0,0 +1,72 @@ +// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma +// de Barcelona (UAB). +// Copyright (c) 2019 Intel Corporation +// +// This work is licensed under the terms of the MIT license. +// For a copy, see . + +#pragma once + +#include "BaseCarlaMovementComponent.h" +#include "Carla/Vehicle/VehicleControl.h" + +#ifdef WITH_CARSIM +#include "CarSimMovementComponent.h" +#endif + +#include "CarSimManagerComponent.generated.h" + +class ACarlaWheeledVehicle; + +UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent) ) +class CARLA_API UCarSimManagerComponent : public UBaseCarlaMovementComponent +{ + GENERATED_BODY() + + #ifdef WITH_CARSIM + AActor* OffsetActor; + + UCarSimMovementComponent * CarSimMovementComponent; + #endif + +public: + + static void CreateCarsimComponent( + ACarlaWheeledVehicle* Vehicle, FString Simfile); + + FString SimfilePath = ""; + + virtual void BeginPlay() override; + + void ProcessControl(FVehicleControl &Control) override; + + FVector GetVelocity() const override; + + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + + void UseCarSimRoad(bool bEnabled); + + int32 GetVehicleCurrentGear() const override; + + float GetVehicleForwardSpeed() const override; + +private: + + // On car mesh hit, only works when carsim is enabled + UFUNCTION() + void OnCarSimHit(AActor *Actor, + AActor *OtherActor, + FVector NormalImpulse, + const FHitResult &Hit); + + // On car mesh overlap, only works when carsim is enabled + // (this event triggers when overlapping with static environment) + UFUNCTION() + void OnCarSimOverlap(UPrimitiveComponent* OverlappedComponent, + AActor* OtherActor, + UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex, + bool bFromSweep, + const FHitResult & SweepResult); + +}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/DefaultMovementComponent.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/DefaultMovementComponent.cpp new file mode 100644 index 000000000..fea2eb3a9 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/DefaultMovementComponent.cpp @@ -0,0 +1,55 @@ +// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma +// de Barcelona (UAB). +// Copyright (c) 2019 Intel Corporation +// +// This work is licensed under the terms of the MIT license. +// For a copy, see . + +#include "DefaultMovementComponent.h" + +void UDefaultMovementComponent::CreateDefaultMovementComponent(ACarlaWheeledVehicle* Vehicle) +{ + UDefaultMovementComponent* DefaultMovementComponent = NewObject(Vehicle); + DefaultMovementComponent->RegisterComponent(); + Vehicle->SetCarlaMovementComponent(DefaultMovementComponent); +} + +void UDefaultMovementComponent::BeginPlay() +{ + Super::BeginPlay(); +} + +void UDefaultMovementComponent::ProcessControl(FVehicleControl &Control) +{ + auto *MovementComponent = CarlaVehicle->GetVehicleMovementComponent(); + MovementComponent->SetThrottleInput(Control.Throttle); + MovementComponent->SetSteeringInput(Control.Steer); + MovementComponent->SetBrakeInput(Control.Brake); + MovementComponent->SetHandbrakeInput(Control.bHandBrake); + if (CarlaVehicle->GetVehicleControl().bReverse != Control.bReverse) + { + MovementComponent->SetUseAutoGears(!Control.bReverse); + MovementComponent->SetTargetGear(Control.bReverse ? -1 : 1, true); + } + else + { + MovementComponent->SetUseAutoGears(!Control.bManualGearShift); + if (Control.bManualGearShift) + { + MovementComponent->SetTargetGear(Control.Gear, true); + } + } + Control.Gear = MovementComponent->GetCurrentGear(); +} + +// FVector GetVelocity() const override; + +int32 UDefaultMovementComponent::GetVehicleCurrentGear() const +{ + return CarlaVehicle->GetVehicleMovementComponent()->GetCurrentGear(); +} + +float UDefaultMovementComponent::GetVehicleForwardSpeed() const +{ + return CarlaVehicle->GetVehicleMovementComponent()->GetForwardSpeed(); +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/DefaultMovementComponent.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/DefaultMovementComponent.h new file mode 100644 index 000000000..21a762dbc --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/DefaultMovementComponent.h @@ -0,0 +1,34 @@ +// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma +// de Barcelona (UAB). +// Copyright (c) 2019 Intel Corporation +// +// This work is licensed under the terms of the MIT license. +// For a copy, see . + +#pragma once + +#include "BaseCarlaMovementComponent.h" +#include "DefaultMovementComponent.generated.h" + + +UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent) ) +class CARLA_API UDefaultMovementComponent : public UBaseCarlaMovementComponent +{ + GENERATED_BODY() + +public: + + static void CreateDefaultMovementComponent(ACarlaWheeledVehicle* Vehicle); + + virtual void BeginPlay() override; + + void ProcessControl(FVehicleControl &Control) override; + + // FVector GetVelocity() const override; + + int32 GetVehicleCurrentGear() const override; + + float GetVehicleForwardSpeed() const override; + +}; +