Improved movement components vehicle interface.

This commit is contained in:
Axel 2021-01-20 13:31:53 +01:00 committed by Axel1092
parent 3e3b7fcb20
commit c0986a07fc
10 changed files with 462 additions and 303 deletions

View File

@ -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 <compiler/disable-ue4-macros.h>
#include <carla/Functional.h>
@ -919,7 +920,11 @@ void FCarlaServer::FPimpl::BindActions()
auto* CarlaVehicle = Cast<ACarlaWheeledVehicle>(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<UCarSimManagerComponent>())
{
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<void>::Success();
};
//-----CARSIM--------------------------------
BIND_SYNC(enable_carsim) << [this](
cr::ActorId ActorId,
std::string SimfilePath) -> R<void>
{
#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<void>::Success();
#else
RESPOND_ERROR("CarSim plugin is not enabled");
#endif
};
BIND_SYNC(use_carsim_road) << [this](
cr::ActorId ActorId,
bool bEnabled) -> R<void>
{
#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<UCarSimManagerComponent>();
if(CarSimComponent)
{
CarSimComponent->UseCarSimRoad(bEnabled);
}
else
{
RESPOND_ERROR("UCarSimManagerComponent plugin is not activated");
}
return R<void>::Success();
#else
RESPOND_ERROR("CarSim plugin is not enabled");
#endif
};
//-----CARSIM--------------------------------
// ~~ Traffic lights ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BIND_SYNC(set_traffic_light_state) << [this](

View File

@ -9,6 +9,8 @@
#include <carla/rpc/ObjectLabel.h>
#include <compiler/enable-ue4-macros.h>
#include "BoundingBox.h"
#include "EnvironmentObject.generated.h"
namespace crp = carla::rpc;

View File

@ -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<UVehicleVelocityControl>(TEXT("VelocityControl"));
VelocityControl->Deactivate();
#ifdef WITH_CARSIM
// ExternalMovementComponent = CreateDefaultSubobject<UCarSimMovementComponent>(TEXT("CarSimMovement"));
// CarSimMovementComponent = Cast<UCarSimMovementComponent>(ExternalMovementComponent);
// CarSimMovementComponent->DisableVehicle = true;
#endif
GetVehicleMovementComponent()->bReverseAsBrake = false;
BaseMovementComponent = CreateDefaultSubobject<UBaseCarlaMovementComponent>(TEXT("BaseMovementComponent"));
}
ACarlaWheeledVehicle::~ACarlaWheeledVehicle() {}
@ -76,6 +73,8 @@ void ACarlaWheeledVehicle::BeginPlay()
{
Super::BeginPlay();
UDefaultMovementComponent::CreateDefaultMovementComponent(this);
float FrictionScale = 3.5f;
UWheeledVehicleMovementComponent4W *Vehicle4W = Cast<UWheeledVehicleMovementComponent4W>(
@ -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<AEmptyActor>(
GetActorLocation() + GetActorForwardVector() * CarSimOriginOffset,
GetActorRotation(),
SpawnParams);
CarSimMovementComponent = NewObject<UCarSimMovementComponent>(OffsetActor);
// CarSimMovementComponent = NewObject<UCarSimMovementComponent>(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<UCarSimManagerComponent>())
{
auto RootComponent = Cast<UPrimitiveComponent>(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
}
//-------------------------------------------

View File

@ -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<float> &WheelsFrictionScale);
void SetCarlaMovementComponent(UBaseCarlaMovementComponent* MoementComponent);
template<typename T = UBaseCarlaMovementComponent>
T* GetCarlaMovementComponent() const
{
return Cast<T>(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
//-------------------------------------------
};

View File

@ -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 <https://opensource.org/licenses/MIT>.
#include "BaseCarlaMovementComponent.h"
#include "Carla/Vehicle/CarlaWheeledVehicle.h"
void UBaseCarlaMovementComponent::BeginPlay()
{
Super::BeginPlay();
ACarlaWheeledVehicle* Vehicle = Cast<ACarlaWheeledVehicle>(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;
}

View File

@ -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 <https://opensource.org/licenses/MIT>.
#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;
};

View File

@ -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 <https://opensource.org/licenses/MIT>.
#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<UCarSimManagerComponent>(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<AEmptyActor>(
CarlaVehicle->GetActorLocation() + CarlaVehicle->GetActorForwardVector() * CarlaVehicle->CarSimOriginOffset,
CarlaVehicle->GetActorRotation(),
SpawnParams);
CarSimMovementComponent = NewObject<UCarSimMovementComponent>(OffsetActor);
// CarSimMovementComponent = NewObject<UCarSimMovementComponent>(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
}

View File

@ -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 <https://opensource.org/licenses/MIT>.
#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);
};

View File

@ -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 <https://opensource.org/licenses/MIT>.
#include "DefaultMovementComponent.h"
void UDefaultMovementComponent::CreateDefaultMovementComponent(ACarlaWheeledVehicle* Vehicle)
{
UDefaultMovementComponent* DefaultMovementComponent = NewObject<UDefaultMovementComponent>(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();
}

View File

@ -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 <https://opensource.org/licenses/MIT>.
#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;
};