First version
This commit is contained in:
parent
e2d0127aae
commit
1220b5a669
|
@ -6,16 +6,22 @@
|
||||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
#include "CarSimManagerComponent.h"
|
#include "CarSimManagerComponent.h"
|
||||||
|
#include "Carla/Game/CarlaEngine.h"
|
||||||
#include "Carla/Vehicle/CarlaWheeledVehicle.h"
|
#include "Carla/Vehicle/CarlaWheeledVehicle.h"
|
||||||
#include "Carla/Util/EmptyActor.h"
|
#include "Carla/Util/EmptyActor.h"
|
||||||
|
|
||||||
|
#ifdef WITH_CARSIM
|
||||||
|
#include "CarSimMovementComponent.h"
|
||||||
|
#include "VsVar.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void UCarSimManagerComponent::CreateCarsimComponent(
|
void UCarSimManagerComponent::CreateCarsimComponent(
|
||||||
ACarlaWheeledVehicle* Vehicle, FString Simfile)
|
ACarlaWheeledVehicle* Vehicle, FString Simfile, int ForceFrames)
|
||||||
{
|
{
|
||||||
#ifdef WITH_CARSIM
|
#ifdef WITH_CARSIM
|
||||||
UCarSimManagerComponent* CarSimManagerComponent = NewObject<UCarSimManagerComponent>(Vehicle);
|
UCarSimManagerComponent* CarSimManagerComponent = NewObject<UCarSimManagerComponent>(Vehicle);
|
||||||
CarSimManagerComponent->SimfilePath = Simfile;
|
CarSimManagerComponent->SimfilePath = Simfile;
|
||||||
|
CarSimManagerComponent->FramesApplyingForce = ForceFrames;
|
||||||
CarSimManagerComponent->RegisterComponent();
|
CarSimManagerComponent->RegisterComponent();
|
||||||
Vehicle->SetCarlaMovementComponent(CarSimManagerComponent);
|
Vehicle->SetCarlaMovementComponent(CarSimManagerComponent);
|
||||||
#else
|
#else
|
||||||
|
@ -68,6 +74,7 @@ void UCarSimManagerComponent::BeginPlay()
|
||||||
// set callbacks to react to collisions
|
// set callbacks to react to collisions
|
||||||
CarlaVehicle->OnActorHit.AddDynamic(this, &UCarSimManagerComponent::OnCarSimHit);
|
CarlaVehicle->OnActorHit.AddDynamic(this, &UCarSimManagerComponent::OnCarSimHit);
|
||||||
CarlaVehicle->GetMesh()->OnComponentBeginOverlap.AddDynamic(this, &UCarSimManagerComponent::OnCarSimOverlap);
|
CarlaVehicle->GetMesh()->OnComponentBeginOverlap.AddDynamic(this, &UCarSimManagerComponent::OnCarSimOverlap);
|
||||||
|
CarlaVehicle->GetMesh()->OnComponentEndOverlap.AddDynamic(this, &UCarSimManagerComponent::OnCarSimEndOverlap);
|
||||||
CarlaVehicle->GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Overlap);
|
CarlaVehicle->GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Overlap);
|
||||||
|
|
||||||
// workaround to prevent carsim from interacting with its own car
|
// workaround to prevent carsim from interacting with its own car
|
||||||
|
@ -81,6 +88,35 @@ void UCarSimManagerComponent::BeginPlay()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UCarSimManagerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
||||||
|
{
|
||||||
|
#ifdef WITH_CARSIM
|
||||||
|
|
||||||
|
// get current vehicle position
|
||||||
|
const auto Trans = CarlaVehicle->GetActorTransform().GetTranslation();
|
||||||
|
// get current velocity
|
||||||
|
auto Root = Cast<UPrimitiveComponent>(CarlaVehicle->GetRootComponent());
|
||||||
|
if (Root == nullptr) return;
|
||||||
|
FVector Vel = Root->GetPhysicsLinearVelocity("None");
|
||||||
|
FVector Dir = Trans + (Vel.GetSafeNormal() * 200.0f);
|
||||||
|
DrawDebugLine(GetWorld(), Trans, Dir, FColor(255, 255, 255), true, 1);
|
||||||
|
|
||||||
|
if (ResetForces != 0 && ResetForces <= FCarlaEngine::FrameCounter)
|
||||||
|
{
|
||||||
|
#undef GetObject
|
||||||
|
TScriptInterface<IVsVar> FX, FY, FZ;
|
||||||
|
FX = IVsConnectObject::Execute_GetVsVar(CarSimMovementComponent, "IMP_FX_RP_1", "", EVsVarDirection::Input);
|
||||||
|
FY = IVsConnectObject::Execute_GetVsVar(CarSimMovementComponent, "IMP_FY_RP_1", "", EVsVarDirection::Input);
|
||||||
|
FZ = IVsConnectObject::Execute_GetVsVar(CarSimMovementComponent, "IMP_FZ_RP_1", "", EVsVarDirection::Input);
|
||||||
|
IVsVar::Execute_SetFloatValue(FX.GetObject(), 0.0f);
|
||||||
|
IVsVar::Execute_SetFloatValue(FY.GetObject(), 0.0f);
|
||||||
|
IVsVar::Execute_SetFloatValue(FZ.GetObject(), 0.0f);
|
||||||
|
ResetForces = 0;
|
||||||
|
UE_LOG(LogCarla, Warning, TEXT("Carsim: Reset forces") );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void UCarSimManagerComponent::ProcessControl(FVehicleControl &Control)
|
void UCarSimManagerComponent::ProcessControl(FVehicleControl &Control)
|
||||||
{
|
{
|
||||||
#ifdef WITH_CARSIM
|
#ifdef WITH_CARSIM
|
||||||
|
@ -95,6 +131,11 @@ void UCarSimManagerComponent::ProcessControl(FVehicleControl &Control)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UCarSimMovementComponent *UCarSimManagerComponent::GetCarsimMovementComponent()
|
||||||
|
// {
|
||||||
|
// return CarSimMovementComponent;
|
||||||
|
// }
|
||||||
|
|
||||||
void UCarSimManagerComponent::OnCarSimHit(AActor *Actor,
|
void UCarSimManagerComponent::OnCarSimHit(AActor *Actor,
|
||||||
AActor *OtherActor,
|
AActor *OtherActor,
|
||||||
FVector NormalImpulse,
|
FVector NormalImpulse,
|
||||||
|
@ -118,11 +159,69 @@ void UCarSimManagerComponent::OnCarSimOverlap(UPrimitiveComponent* OverlappedCom
|
||||||
ECollisionResponse::ECR_Block)
|
ECollisionResponse::ECR_Block)
|
||||||
{
|
{
|
||||||
#ifdef WITH_CARSIM
|
#ifdef WITH_CARSIM
|
||||||
// handle collision forces here
|
// get current vehicle position
|
||||||
|
const auto Trans = CarlaVehicle->GetActorTransform().GetTranslation();
|
||||||
|
// get current velocity
|
||||||
|
auto Root = Cast<UPrimitiveComponent>(CarlaVehicle->GetRootComponent());
|
||||||
|
if (Root == nullptr)
|
||||||
|
return;
|
||||||
|
FVector Vel = Root->GetPhysicsLinearVelocity("None");
|
||||||
|
// reflect the velocity vector with the normal vector
|
||||||
|
FVector NewVel = Vel - (2 * (FVector::DotProduct(Vel, SweepResult.ImpactNormal)) * SweepResult.ImpactNormal);
|
||||||
|
// get the mass of the vehicle
|
||||||
|
FVector Impulse = NewVel * Root->GetMass(); // / FramesApplyingForce;
|
||||||
|
// apply delta time
|
||||||
|
Impulse *= GetWorld()->GetDeltaSeconds();
|
||||||
|
|
||||||
|
// FVector Dir = Trans + (Impulse.GetSafeNormal() * 200.0f);
|
||||||
|
FVector Dir = SweepResult.ImpactPoint + (SweepResult.ImpactNormal * 200.0f);
|
||||||
|
DrawDebugLine(GetWorld(), SweepResult.ImpactPoint, Dir, FColor(255, 0, 0), true, 5, 255, 10);
|
||||||
|
|
||||||
|
// send the force to Carsim
|
||||||
|
#undef GetObject
|
||||||
|
TScriptInterface<IVsVar> FX, FY, FZ;
|
||||||
|
FX = IVsConnectObject::Execute_GetVsVar(CarSimMovementComponent, "IMP_FX_RP_1", "", EVsVarDirection::Input);
|
||||||
|
FY = IVsConnectObject::Execute_GetVsVar(CarSimMovementComponent, "IMP_FY_RP_1", "", EVsVarDirection::Input);
|
||||||
|
FZ = IVsConnectObject::Execute_GetVsVar(CarSimMovementComponent, "IMP_FZ_RP_1", "", EVsVarDirection::Input);
|
||||||
|
IVsVar::Execute_SetFloatValue(FX.GetObject(), Impulse.X);
|
||||||
|
IVsVar::Execute_SetFloatValue(FY.GetObject(), Impulse.Y);
|
||||||
|
IVsVar::Execute_SetFloatValue(FZ.GetObject(), 0.0f);
|
||||||
|
// mark to reset this force next tick
|
||||||
|
ResetForces = FCarlaEngine::FrameCounter + FramesApplyingForce;
|
||||||
|
UE_LOG(LogCarla, Warning, TEXT("Carsim: Applied force: %f (%f, %f, %f) %f"), Root->GetMass(), Impulse.X, Impulse.Y, Impulse.Z, GetWorld()->GetDeltaSeconds());
|
||||||
|
UE_LOG(LogCarla, Warning, TEXT("Carsim: : (%f, %f, %f)"), SweepResult.Normal.X, SweepResult.Normal.Y, SweepResult.Normal.Z);
|
||||||
|
UE_LOG(LogCarla, Warning, TEXT("Carsim: : (%f, %f, %f)"), SweepResult.ImpactNormal.X, SweepResult.ImpactNormal.Y, SweepResult.ImpactNormal.Z);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UCarSimManagerComponent::OnCarSimEndOverlap(UPrimitiveComponent* OverlappedComponent,
|
||||||
|
AActor* OtherActor,
|
||||||
|
UPrimitiveComponent* OtherComp,
|
||||||
|
int32 OtherBodyIndex)
|
||||||
|
{
|
||||||
|
// if (OtherComp->GetCollisionResponseToChannel(
|
||||||
|
// ECollisionChannel::ECC_WorldDynamic) ==
|
||||||
|
// ECollisionResponse::ECR_Block)
|
||||||
|
// {
|
||||||
|
// #ifdef WITH_CARSIM
|
||||||
|
// // if (ResetForces != 0 && ResetForces <= FCarlaEngine::FrameCounter)
|
||||||
|
// // {
|
||||||
|
// #undef GetObject
|
||||||
|
// TScriptInterface<IVsVar> FX, FY, FZ;
|
||||||
|
// FX = IVsConnectObject::Execute_GetVsVar(CarSimMovementComponent, "IMP_FX_RP_1", "", EVsVarDirection::Input);
|
||||||
|
// FY = IVsConnectObject::Execute_GetVsVar(CarSimMovementComponent, "IMP_FY_RP_1", "", EVsVarDirection::Input);
|
||||||
|
// FZ = IVsConnectObject::Execute_GetVsVar(CarSimMovementComponent, "IMP_FZ_RP_1", "", EVsVarDirection::Input);
|
||||||
|
// IVsVar::Execute_SetFloatValue(FX.GetObject(), 0.0f);
|
||||||
|
// IVsVar::Execute_SetFloatValue(FY.GetObject(), 0.0f);
|
||||||
|
// IVsVar::Execute_SetFloatValue(FZ.GetObject(), 0.0f);
|
||||||
|
// // ResetForces = 0;
|
||||||
|
// UE_LOG(LogCarla, Warning, TEXT("Carsim: Reset forces") );
|
||||||
|
// // }
|
||||||
|
// #endif
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
void UCarSimManagerComponent::UseCarSimRoad(bool bEnabled)
|
void UCarSimManagerComponent::UseCarSimRoad(bool bEnabled)
|
||||||
{
|
{
|
||||||
#ifdef WITH_CARSIM
|
#ifdef WITH_CARSIM
|
||||||
|
|
|
@ -32,12 +32,14 @@ class CARLA_API UCarSimManagerComponent : public UBaseCarlaMovementComponent
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void CreateCarsimComponent(
|
static void CreateCarsimComponent(
|
||||||
ACarlaWheeledVehicle* Vehicle, FString Simfile);
|
ACarlaWheeledVehicle* Vehicle, FString Simfile, int ForceFrames = 1);
|
||||||
|
|
||||||
FString SimfilePath = "";
|
FString SimfilePath = "";
|
||||||
|
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
|
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||||
|
|
||||||
void ProcessControl(FVehicleControl &Control) override;
|
void ProcessControl(FVehicleControl &Control) override;
|
||||||
|
|
||||||
FVector GetVelocity() const override;
|
FVector GetVelocity() const override;
|
||||||
|
@ -50,8 +52,13 @@ public:
|
||||||
|
|
||||||
float GetVehicleForwardSpeed() const override;
|
float GetVehicleForwardSpeed() const override;
|
||||||
|
|
||||||
|
// UCarSimMovementComponent *GetCarsimMovementComponent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
uint64_t ResetForces { 0 };
|
||||||
|
int FramesApplyingForce { 1 };
|
||||||
|
|
||||||
// On car mesh hit, only works when carsim is enabled
|
// On car mesh hit, only works when carsim is enabled
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
void OnCarSimHit(AActor *Actor,
|
void OnCarSimHit(AActor *Actor,
|
||||||
|
@ -69,4 +76,11 @@ private:
|
||||||
bool bFromSweep,
|
bool bFromSweep,
|
||||||
const FHitResult & SweepResult);
|
const FHitResult & SweepResult);
|
||||||
|
|
||||||
|
// On car mesh overlap end, only works when carsim is enabled
|
||||||
|
// (this event triggers when overlapping with static environment)
|
||||||
|
UFUNCTION()
|
||||||
|
void OnCarSimEndOverlap(UPrimitiveComponent* OverlappedComponent,
|
||||||
|
AActor* OtherActor,
|
||||||
|
UPrimitiveComponent* OtherComp,
|
||||||
|
int32 OtherBodyIndex);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue