diff --git a/Unreal/Environments/Blocks/Config/DefaultEditor.ini b/Unreal/Environments/Blocks/Config/DefaultEditor.ini index 481fbf2d4..f44257a4d 100644 --- a/Unreal/Environments/Blocks/Config/DefaultEditor.ini +++ b/Unreal/Environments/Blocks/Config/DefaultEditor.ini @@ -7,3 +7,5 @@ bReplaceBlueprintWithClass= true bDontLoadBlueprintOutsideEditor= true bBlueprintIsNotBlueprintType= true +[/Script/AdvancedPreviewScene.SharedProfiles] + diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicle.cpp b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicle.cpp deleted file mode 100644 index 0374388db..000000000 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicle.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Based on the work by Leon Rosengarten and Boone Adkins. -// https://github.com/b-adkins/UE4-TankVehiclePlugin -// Developed by Cosys-Lab, University of Antwerp - -#include "SkidVehicle.h" -#include "SkidVehicleMovementComponent.h" - -ASkidVehicle::ASkidVehicle(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) -{ - - -} - -// Called when the game starts or when spawned -void ASkidVehicle::BeginPlay() -{ - Super::BeginPlay(); - -} - -// Called every frame -void ASkidVehicle::Tick(float DeltaTime) -{ - Super::Tick(DeltaTime); - -} - -// Called to bind functionality to input -void ASkidVehicle::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) -{ - - Super::SetupPlayerInputComponent(PlayerInputComponent); - -} - -void ASkidVehicle::PostInitializeComponents() -{ - Super::PostInitializeComponents(); -} - -class USkidVehicleMovementComponent* ASkidVehicle::GetSkidVehicleMovement() const -{ - class USkidVehicleMovementComponent* SkidMovmentComponent = Cast(GetVehicleMovement()); - return SkidMovmentComponent; -} - - - -void ASkidVehicle::SetXJoy(float nJoyX) -{ - USkidVehicleMovementComponent* SkidMovmentComponent = Cast(GetVehicleMovement()); - - if (SkidMovmentComponent) - { - SkidMovmentComponent->SetXJoy(nJoyX); - } -} - -void ASkidVehicle::SetYJoy(float nJoyY) -{ - USkidVehicleMovementComponent* SkidMovmentComponent = Cast(GetVehicleMovement()); - - if (SkidMovmentComponent) - { - SkidMovmentComponent->SetYJoy(nJoyY); - } -} - -void ASkidVehicle::SetBreaksOn() -{ - USkidVehicleMovementComponent* SkidMovmentComponent = Cast(GetVehicleMovement()); - - if (SkidMovmentComponent) - { - SkidMovmentComponent->SetBreaksOn(); - } -} - -void ASkidVehicle::SetBreaksOff() -{ - USkidVehicleMovementComponent* SkidMovmentComponent = Cast(GetVehicleMovement()); - - if (SkidMovmentComponent) - { - SkidMovmentComponent->SetBreaksOff(); - } -} diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicle.h b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicle.h deleted file mode 100644 index 1dab0f69f..000000000 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicle.h +++ /dev/null @@ -1,49 +0,0 @@ -// Based on the work by Leon Rosengarten and Boone Adkins. -// https://github.com/b-adkins/UE4-TankVehiclePlugin -// Developed by Cosys-Lab, University of Antwerp - -#pragma once - -#include "CoreMinimal.h" -#include "ChaosWheeledVehicleMovementComponent.h" -#include "WheeledVehiclePawn.h" -#include "SkidVehicle.generated.h" - -/** - * - */ -UCLASS() -class AIRSIM_API ASkidVehicle : public AWheeledVehiclePawn -{ - GENERATED_UCLASS_BODY() - -public: - - // Called when the game starts or when spawned - virtual void BeginPlay() override; - - // Called every frame - virtual void Tick(float DeltaSeconds) override; - - // Called to bind functionality to input - virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; - - virtual void PostInitializeComponents() override; - - class USkidVehicleMovementComponent* GetSkidVehicleMovement() const; - -public: - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetXJoy(float XThrust); - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetYJoy(float YThrust); - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetBreaksOn(); - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetBreaksOff(); -}; - diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleAnimInstance.cpp b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleAnimInstance.cpp deleted file mode 100644 index 7d55cd98e..000000000 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleAnimInstance.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Based on the work by Leon Rosengarten and Boone Adkins. -// https://github.com/b-adkins/UE4-TankVehiclePlugin -// Developed by Cosys-Lab, University of Antwerp - -#include "SkidVehicleAnimInstance.h" -#include "SkidVehicle.h" -#include "AnimationRuntime.h" - -USkidVehicleAnimInstance::USkidVehicleAnimInstance(const FObjectInitializer& ObjectInitializer) - : Super(ObjectInitializer) -{ -} - -class ASkidVehicle* USkidVehicleAnimInstance::GetSkidVehicle() -{ - return Cast(GetOwningActor()); -} \ No newline at end of file diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleAnimInstance.h b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleAnimInstance.h deleted file mode 100644 index 555489c0e..000000000 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleAnimInstance.h +++ /dev/null @@ -1,24 +0,0 @@ -// Based on the work by Leon Rosengarten and Boone Adkins. -// https://github.com/b-adkins/UE4-TankVehiclePlugin -// Developed by Cosys-Lab, University of Antwerp - -#pragma once - -#include "CoreMinimal.h" -#include "Vehicles/SkidSteer/SkidVehicle.h" -#include "VehicleAnimationInstance.h" -#include "SkidVehicleAnimInstance.generated.h" - -/** - * - */ -UCLASS(transient) -class AIRSIM_API USkidVehicleAnimInstance : public UVehicleAnimationInstance -{ - GENERATED_UCLASS_BODY() - - /** Makes a montage jump to the end of a named section. */ - UFUNCTION(BlueprintCallable, Category = "Animation") - class ASkidVehicle * GetSkidVehicle(); - -}; diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleMovementComponent.cpp b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleMovementComponent.cpp deleted file mode 100644 index 1ff5de0f9..000000000 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleMovementComponent.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// Based on the work by Leon Rosengarten and Boone Adkins. -// https://github.com/b-adkins/UE4-TankVehiclePlugin -// Developed by Cosys-Lab, University of Antwerp - -#include "SkidVehicleMovementComponent.h" -#include "Components/PrimitiveComponent.h" - - -FVehicleTransmissionDataSkid::FVehicleTransmissionDataSkid() - : bUseGearAutoBox(true) - , GearSwitchTime(0.0f) - , GearAutoBoxLatency(0.0f) - , FinalRatio(1.0f) - , ReverseGearRatio(0.0f) - , NeutralGearUpRatio(0.0f) - , ClutchStrength(0.0f) -{ - -} - -FVehicleGearDataSkid::FVehicleGearDataSkid() - : Ratio(1.0f) - , DownRatio(0.0f) - , UpRatio(1.0f) -{ - -} - -FVehicleEngineDataSkid::FVehicleEngineDataSkid() - : MaxRPM(0.0f) - , MOI(0.0f) - , DampingRateFullThrottle(0.0f) - , DampingRateZeroThrottleClutchEngaged(0.0f) - , DampingRateZeroThrottleClutchDisengaged(0.0f) -{ - -} - -float FVehicleEngineDataSkid::FindPeakTorque() const -{ - // Find max torque - float PeakTorque = 0.f; - TArray TorqueKeys = TorqueCurve.GetRichCurveConst()->GetCopyOfKeys(); - for (int32 KeyIdx = 0; KeyIdx < TorqueKeys.Num(); KeyIdx++) - { - FRichCurveKey& Key = TorqueKeys[KeyIdx]; - PeakTorque = FMath::Max(PeakTorque, Key.Value); - } - return PeakTorque; -} - - -USkidVehicleMovementComponent::USkidVehicleMovementComponent(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) -{ - // Initialize WheelSetups array with 4 wheels - WheelSetups.SetNum(4); -} - -float FindSkidPeakTorque(const FVehicleEngineDataSkid& Setup) -{ - // Find max torque - float PeakTorque = 0.f; - TArray TorqueKeys = Setup.TorqueCurve.GetRichCurveConst()->GetCopyOfKeys(); - for (int32 KeyIdx = 0; KeyIdx < TorqueKeys.Num(); KeyIdx++) - { - FRichCurveKey& Key = TorqueKeys[KeyIdx]; - PeakTorque = FMath::Max(PeakTorque, Key.Value); - } - return PeakTorque; -} - -void USkidVehicleMovementComponent::SetupVehicle(TUniquePtr& PVehicle) -{ - - if (!UpdatedPrimitive) - { - return; - } - - if (WheelSetups.Num() % 2 != 0 && WheelSetups.Num() > 20) - { - PVehicle = NULL; - return; - } - - - - for (int32 WheelIdx = 0; WheelIdx < WheelSetups.Num(); ++WheelIdx) - { - const FChaosWheelSetup& WheelSetup = WheelSetups[WheelIdx]; - if (WheelSetup.BoneName == NAME_None) - { - return; - } - } - - Super::SetupVehicle(PVehicle); -} - -#if WITH_EDITOR -void USkidVehicleMovementComponent::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) -{ - Super::PostEditChangeProperty(PropertyChangedEvent); -} -#endif - -void USkidVehicleMovementComponent::SetAcceleration(float OtherAcceleration) -{ - this->Acceleration = OtherAcceleration; -} - -void USkidVehicleMovementComponent::SetLeftBreak(float OtherLeftBreak) -{ - this->LeftBreak = OtherLeftBreak; - SetBrakeInput(GetLeftBreak()); -} - -void USkidVehicleMovementComponent::SetRightBreak(float OtherRightBreak) -{ - this->RightBreak = OtherRightBreak; - SetBrakeInput(GetRightBreak()); - -} - -void USkidVehicleMovementComponent::SetYJoy(float OtherNJoyY) -{ - this->nJoyY = OtherNJoyY; -} - -void USkidVehicleMovementComponent::SetXJoy(float OtherNJoyX) -{ - this->nJoyX = OtherNJoyX; - float accel = FMath::Min((float)sqrt(nJoyX * nJoyX + nJoyY * nJoyY), 1.0f); - SetThrottleInput(GetAcceleration()); - SetYawInput(nJoyX); -} - -float USkidVehicleMovementComponent::GetAcceleration() const -{ - return Acceleration; -} - -float USkidVehicleMovementComponent::GetLeftBreak() const -{ - return LeftBreak; -} - -float USkidVehicleMovementComponent::GetRightBreak() const -{ - return RightBreak; -} - -float USkidVehicleMovementComponent::GetYJoy() const -{ - return nJoyY; -} - -float USkidVehicleMovementComponent::GetXJoy() const -{ - return nJoyX; -} - -void USkidVehicleMovementComponent::SetBreaksOn() -{ - this->toggleBreak = true; - SetAcceleration(0); - SetLeftBreak(1); - SetParked(1); -} - -void USkidVehicleMovementComponent::SetBreaksOff() -{ - this->toggleBreak = false; - SetParked(0); -} \ No newline at end of file diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleMovementComponent.h b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleMovementComponent.h deleted file mode 100644 index 3b8187e32..000000000 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehicleMovementComponent.h +++ /dev/null @@ -1,204 +0,0 @@ -// Based on the work by Leon Rosengarten and Boone Adkins. -// https://github.com/b-adkins/UE4-TankVehiclePlugin -// Developed by Cosys-Lab, University of Antwerp - -#pragma once - -#include "CoreMinimal.h" -#include "ChaosWheeledVehicleMovementComponent.h" -#include "Curves/CurveFloat.h" -#include "UObject/ObjectMacros.h" -#include "SkidVehicleMovementComponent.generated.h" - - -UENUM() -namespace EVehicleDifferential4WSkid -{ - enum Type - { - LimitedSlip_4W, - LimitedSlip_FrontDrive, - LimitedSlip_RearDrive, - Open_4W, - Open_FrontDrive, - Open_RearDrive, - }; -} - -USTRUCT() -struct FVehicleEngineDataSkid -{ - GENERATED_BODY() - - FVehicleEngineDataSkid(); - - /** Torque (Nm) at a given RPM*/ - UPROPERTY(EditAnywhere, Category = Setup) - FRuntimeFloatCurve TorqueCurve; - - /** Maximum revolutions per minute of the engine */ - UPROPERTY(EditAnywhere, Category = Setup, meta = (ClampMin = "0.01", UIMin = "0.01")) - float MaxRPM; - - /** Moment of inertia of the engine around the axis of rotation (Kgm^2). */ - UPROPERTY(EditAnywhere, Category = Setup, meta = (ClampMin = "0.01", UIMin = "0.01")) - float MOI; - - /** Damping rate of engine when full throttle is applied (Kgm^2/s) */ - UPROPERTY(EditAnywhere, Category = Setup, AdvancedDisplay, meta = (ClampMin = "0.0", UIMin = "0.0")) - float DampingRateFullThrottle; - - /** Damping rate of engine in at zero throttle when the clutch is engaged (Kgm^2/s)*/ - UPROPERTY(EditAnywhere, Category = Setup, AdvancedDisplay, meta = (ClampMin = "0.0", UIMin = "0.0")) - float DampingRateZeroThrottleClutchEngaged; - - /** Damping rate of engine in at zero throttle when the clutch is disengaged (in neutral gear) (Kgm^2/s)*/ - UPROPERTY(EditAnywhere, Category = Setup, AdvancedDisplay, meta = (ClampMin = "0.0", UIMin = "0.0")) - float DampingRateZeroThrottleClutchDisengaged; - - /** Find the peak torque produced by the TorqueCurve */ - float FindPeakTorque() const; -}; - - -USTRUCT() -struct FVehicleGearDataSkid -{ - GENERATED_BODY() - - FVehicleGearDataSkid(); - - /** Determines the amount of torque multiplication*/ - UPROPERTY(EditAnywhere, Category = Setup) - float Ratio; - - /** Value of engineRevs/maxEngineRevs that is low enough to gear down*/ - UPROPERTY(EditAnywhere, meta = (ClampMin = "0.0", UIMin = "0.0", ClampMax = "1.0", UIMax = "1.0"), Category = Setup) - float DownRatio; - - /** Value of engineRevs/maxEngineRevs that is high enough to gear up*/ - UPROPERTY(EditAnywhere, meta = (ClampMin = "0.0", UIMin = "0.0", ClampMax = "1.0", UIMax = "1.0"), Category = Setup) - float UpRatio; -}; - -USTRUCT() -struct FVehicleTransmissionDataSkid -{ - GENERATED_BODY() - - FVehicleTransmissionDataSkid(); - - /** Whether to use automatic transmission */ - UPROPERTY(EditAnywhere, Category = VehicleSetup, meta = (DisplayName = "Automatic Transmission")) - bool bUseGearAutoBox; - - /** Time it takes to switch gears (seconds) */ - UPROPERTY(EditAnywhere, Category = Setup, meta = (ClampMin = "0.0", UIMin = "0.0")) - float GearSwitchTime; - - /** Minimum time it takes the automatic transmission to initiate a gear change (seconds)*/ - UPROPERTY(EditAnywhere, Category = Setup, meta = (editcondition = "bUseGearAutoBox", ClampMin = "0.0", UIMin = "0.0")) - float GearAutoBoxLatency; - - /** The final gear ratio multiplies the transmission gear ratios.*/ - UPROPERTY(EditAnywhere, AdvancedDisplay, Category = Setup) - float FinalRatio; - - /** Forward gear ratios (up to 30) */ - UPROPERTY(EditAnywhere, Category = Setup, AdvancedDisplay) - TArray ForwardGears; - - /** Reverse gear ratio */ - UPROPERTY(EditAnywhere, AdvancedDisplay, Category = Setup) - float ReverseGearRatio; - - /** Value of engineRevs/maxEngineRevs that is high enough to increment gear*/ - UPROPERTY(EditAnywhere, AdvancedDisplay, Category = Setup, meta = (ClampMin = "0.0", UIMin = "0.0", ClampMax = "1.0", UIMax = "1.0")) - float NeutralGearUpRatio; - - /** Strength of clutch (Kgm^2/s)*/ - UPROPERTY(EditAnywhere, Category = Setup, AdvancedDisplay, meta = (ClampMin = "0.0", UIMin = "0.0")) - float ClutchStrength; -}; - -UCLASS(ClassGroup = (Physics), meta = (BlueprintSpawnableComponent), hidecategories = (PlanarMovement, "Components|Movement|Planar", Activation, "Components|Activation")) -class AIRSIM_API USkidVehicleMovementComponent : public UChaosWheeledVehicleMovementComponent -{ - GENERATED_UCLASS_BODY() - -public: - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetAcceleration(float Acceleration); - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetLeftBreak(float LeftBreak); - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetRightBreak(float RightBreak); - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetYJoy(float nJoyY); - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetXJoy(float nJoyX); - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - float GetAcceleration() const; - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - float GetLeftBreak() const; - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - float GetRightBreak() const; - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - float GetYJoy() const; - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - float GetXJoy() const; - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetBreaksOn(); - - UFUNCTION(BlueprintCallable, Category = "Game|Components|SkidVehicleMovement") - void SetBreaksOff(); - - -public: - - - UPROPERTY(EditAnywhere, Category = "Skid Setup") - uint32 NumOfWheels; - -public: - -#if WITH_EDITOR - virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override; -#endif - -protected: - - virtual void SetupVehicle(TUniquePtr& PVehicle) override; - -protected: - - - UPROPERTY(Transient) - float Acceleration; - UPROPERTY(Transient) - float LeftBreak; - UPROPERTY(Transient) - float RightBreak; - UPROPERTY(Transient) - float nJoyX; - UPROPERTY(Transient) - float nJoyY; - UPROPERTY(Transient) - bool toggleBreak; - -private: - - - -}; \ No newline at end of file diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawn.cpp b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawn.cpp index 410353eb1..209d43ca0 100755 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawn.cpp +++ b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawn.cpp @@ -7,8 +7,8 @@ #include "Components/AudioComponent.h" #include "Components/StaticMeshComponent.h" #include "Sound/SoundCue.h" -#include "SkidVehicleMovementComponent.h" - +#include "ChaosWheeledVehicleMovementComponent.h" +#include "SkidWheel.h" #include "AirBlueprintLib.h" #include #include "common/common_utils/Utils.hpp" @@ -36,6 +36,8 @@ ASkidVehiclePawn::ASkidVehiclePawn() else UAirBlueprintLib::LogMessageString("Failed to load NonSlippery physics material", "", LogDebugLevel::Failure); + setupVehicleMovementComponent(); + // Create In-Car camera component camera_front_center_base_ = CreateDefaultSubobject(TEXT("camera_front_center_base_")); camera_front_center_base_->SetRelativeLocation(FVector(45, 0, 45)); //center @@ -83,6 +85,73 @@ ASkidVehiclePawn::ASkidVehiclePawn() is_low_friction_ = false; } + +void ASkidVehiclePawn::setupVehicleMovementComponent() +{ + UChaosWheeledVehicleMovementComponent* movement = CastChecked(getVehicleMovementComponent()); + movement->WheelSetups.SetNum(4); + check(movement->WheelSetups.Num() == 4); + + // Wheels/Tires + // Setup the wheels + movement->WheelSetups[0].WheelClass = USkidWheel::StaticClass(); + movement->WheelSetups[0].BoneName = FName("CPHusky_Wheel_FL"); + movement->WheelSetups[0].AdditionalOffset = FVector(0.f, 0.f, 0.f); + + movement->WheelSetups[1].WheelClass = USkidWheel::StaticClass(); + movement->WheelSetups[1].BoneName = FName("CPHusky_Wheel_FR"); + movement->WheelSetups[1].AdditionalOffset = FVector(0.f, 0.f, 0.f); + + movement->WheelSetups[2].WheelClass = USkidWheel::StaticClass(); + movement->WheelSetups[2].BoneName = FName("CPHusky_Wheel_BL"); + movement->WheelSetups[2].AdditionalOffset = FVector(0.f, 0.f, 0.f); + + movement->WheelSetups[3].WheelClass = USkidWheel::StaticClass(); + movement->WheelSetups[3].BoneName = FName("CPHusky_Wheel_BR"); + movement->WheelSetups[3].AdditionalOffset = FVector(0.f, 0.f, 0.f); + + // Engine + // Torque setup + movement->EngineSetup.MaxRPM = 5700.0f; + movement->EngineSetup.TorqueCurve.GetRichCurve()->Reset(); + movement->EngineSetup.TorqueCurve.GetRichCurve()->AddKey(0.0f, 400.0f); + movement->EngineSetup.TorqueCurve.GetRichCurve()->AddKey(1890.0f, 500.0f); + movement->EngineSetup.TorqueCurve.GetRichCurve()->AddKey(5730.0f, 400.0f); + + // Adjust the steering + movement->SteeringSetup.SteeringCurve.GetRichCurve()->Reset(); + movement->SteeringSetup.SteeringCurve.GetRichCurve()->AddKey(0.0f, 1.0f); + movement->SteeringSetup.SteeringCurve.GetRichCurve()->AddKey(40.0f, 0.7f); + movement->SteeringSetup.SteeringCurve.GetRichCurve()->AddKey(120.0f, 0.6f); + + // Transmission + // We want 4wd + movement->DifferentialSetup.DifferentialType = EVehicleDifferential::RearWheelDrive; + + // Drive the front wheels a little more than the rear + movement->DifferentialSetup.FrontRearSplit = 0.65; + + // Automatic gearbox + movement->TransmissionSetup.bUseAutomaticGears = true; + movement->TransmissionSetup.GearChangeTime = 0.15f; + //movement->TransmissionSetup.GearAutoBoxLatency = 1.0f; + + // Disable reverse as brake, this is needed for SetBreakInput() to take effect + movement->bReverseAsBrake = false; + + // Physics settings + // Adjust the center of mass - the buggy is quite low + UPrimitiveComponent* primitive = Cast(movement->UpdatedComponent); + if (primitive) { + primitive->BodyInstance.COMNudge = FVector(8.0f, 0.0f, 0.0f); + } + movement->UpdatedPrimitive = primitive; + // Set the inertia scale. This controls how the mass of the vehicle is distributed. + movement->InertiaTensorScale = FVector(1.0f, 1.333f, 1.2f); + //movement->bDeprecatedSpringOffsetMode = true; + movement->bAutoRegisterUpdatedComponent = true; +} + void ASkidVehiclePawn::NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit) { @@ -90,9 +159,14 @@ void ASkidVehiclePawn::NotifyHit(class UPrimitiveComponent* MyComp, class AActor HitNormal, NormalImpulse, Hit); } -USkidVehicleMovementComponent* ASkidVehiclePawn::getVehicleMovementComponent() const +UChaosVehicleMovementComponent* ASkidVehiclePawn::getVehicleMovementComponent() const { - return GetSkidVehicleMovement(); + return GetVehicleMovement(); +} + +USkeletalMeshComponent* ASkidVehiclePawn::getVehicleMesh() const +{ + return GetMesh(); } void ASkidVehiclePawn::initializeForBeginPlay(bool engine_sound) @@ -171,6 +245,12 @@ void ASkidVehiclePawn::Tick(float Delta) { Super::Tick(Delta); + USkeletalMeshComponent* mesh = CastChecked(getVehicleMesh()); + if (mesh->GetPhysicsAngularVelocityInDegrees().Size() > max_angular_velocity_) + stop_turn_ = true; + else + stop_turn_ = false; + // update physics material updatePhysicsMaterial(); @@ -198,7 +278,6 @@ void ASkidVehiclePawn::BeginPlay() void ASkidVehiclePawn::updateHUDStrings() { - float speed_unit_factor = AirSimSettings::singleton().speed_unit_factor; FText speed_unit_label = FText::FromString(FString(AirSimSettings::singleton().speed_unit_label.c_str())); float vel = FMath::Abs(GetVehicleMovement()->GetForwardSpeed() / 100); //cm/s -> m/s @@ -215,8 +294,7 @@ void ASkidVehiclePawn::updateHUDStrings() else { last_gear_ = (Gear == 0) ? LOCTEXT("N", "N") : FText::AsNumber(Gear); - } - + } UChaosWheeledVehicleMovementComponent* movement = CastChecked(getVehicleMovementComponent()); UAirBlueprintLib::LogMessage(TEXT("Speed: "), last_speed_.ToString(), LogDebugLevel::Informational); UAirBlueprintLib::LogMessage(TEXT("Gear: "), last_gear_.ToString(), LogDebugLevel::Informational); @@ -268,50 +346,64 @@ void ASkidVehiclePawn::setupInputBindings() { //UAirBlueprintLib::EnableInput(this); - UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveY", EKeys::Up, 0.5), this, - this, &ASkidVehiclePawn::onMoveY); - - UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveY", EKeys::Down, -0.5), this, - this, &ASkidVehiclePawn::onMoveY); - - UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveX", EKeys::Right, 0.34), this, - this, &ASkidVehiclePawn::onMoveX); - - UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveX", EKeys::Left, -0.34), this, - this, &ASkidVehiclePawn::onMoveX); - - UAirBlueprintLib::BindActionToKey("Break", EKeys::SpaceBar, this, &ASkidVehiclePawn::onBreakPressed, true); - UAirBlueprintLib::BindActionToKey("Break", EKeys::SpaceBar, this, &ASkidVehiclePawn::onBreakReleased, false); + UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveForward", EKeys::Up, 1), this, this, &ASkidVehiclePawn::onMoveForward); + UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveForward", EKeys::Down, -1), this, this, &ASkidVehiclePawn::onMoveForward); + UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveRight", EKeys::Right, 1), this, this, &ASkidVehiclePawn::onMoveRight); + UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveRight", EKeys::Left, -1), this, this, &ASkidVehiclePawn::onMoveRight); + UAirBlueprintLib::BindActionToKey("Handbrake", EKeys::End, this, &ASkidVehiclePawn::onHandbrakePressed, true); + UAirBlueprintLib::BindActionToKey("Handbrake", EKeys::End, this, &ASkidVehiclePawn::onHandbrakeReleased, false); + UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("Footbrake", EKeys::SpaceBar, 1), this, this, &ASkidVehiclePawn::onFootBrake); + UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveRight", EKeys::Gamepad_LeftX, 1), this, this, &ASkidVehiclePawn::onMoveRight); + UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveForward", EKeys::Gamepad_RightTriggerAxis, 1), this, this, &ASkidVehiclePawn::onMoveForward); + UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("Footbrake", EKeys::Gamepad_LeftTriggerAxis, 1), this, this, &ASkidVehiclePawn::onFootBrake); +} +void ASkidVehiclePawn::onMoveForward(float Val) +{ + if (Val < 0) + onReversePressed(); + else + onReverseReleased(); - UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveX", EKeys::Gamepad_LeftX, 1), this, - this, &ASkidVehiclePawn::onMoveX); + keyboard_controls_.throttle = Val; +} - UAirBlueprintLib::BindAxisToKey(FInputAxisKeyMapping("MoveY", EKeys::Gamepad_LeftY, 1), this, - this, &ASkidVehiclePawn::onMoveY); +void ASkidVehiclePawn::onMoveRight(float Val) +{ + keyboard_controls_.steering = Val; +} - UAirBlueprintLib::BindActionToKey("Break", EKeys::Gamepad_FaceButton_Right, this, &ASkidVehiclePawn::onBreakPressed, true); - UAirBlueprintLib::BindActionToKey("Break", EKeys::Gamepad_FaceButton_Right, this, &ASkidVehiclePawn::onBreakReleased, false); +void ASkidVehiclePawn::onHandbrakePressed() +{ + keyboard_controls_.handbrake = true; } -void ASkidVehiclePawn::onMoveX(float Val) +void ASkidVehiclePawn::onHandbrakeReleased() { - keyboard_controls_.steering = Val; + keyboard_controls_.handbrake = false; } -void ASkidVehiclePawn::onMoveY(float Val) +void ASkidVehiclePawn::onFootBrake(float Val) { - keyboard_controls_.throttle = Val; + keyboard_controls_.brake = Val; } -void ASkidVehiclePawn::onBreakPressed() +void ASkidVehiclePawn::onReversePressed() { - keyboard_controls_.brake = 1; + if (keyboard_controls_.manual_gear >= 0) { + keyboard_controls_.is_manual_gear = true; + keyboard_controls_.manual_gear = -1; + keyboard_controls_.gear_immediate = true; + } } -void ASkidVehiclePawn::onBreakReleased() +void ASkidVehiclePawn::onReverseReleased() { - keyboard_controls_.brake = 0; + if (keyboard_controls_.manual_gear < 0) { + keyboard_controls_.is_manual_gear = false; + keyboard_controls_.manual_gear = 0; + keyboard_controls_.gear_immediate = true; + } } #undef LOCTEXT_NAMESPACE diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawn.h b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawn.h index 00db86257..298d1101f 100644 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawn.h +++ b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawn.h @@ -1,9 +1,8 @@ -// Developed by Cosys-Lab, University of Antwerp - #pragma once #include "CoreMinimal.h" -#include "Vehicles/SkidSteer/SkidVehicle.h" +#include "ChaosWheeledVehicleMovementComponent.h" +#include "WheeledVehiclePawn.h" #include "Components/SkeletalMeshComponent.h" #include "PhysicalMaterials/PhysicalMaterial.h" #include "UObject/ConstructorHelpers.h" @@ -28,86 +27,99 @@ class UInputComponent; class UAudioComponent; UCLASS(config = Game) -class AIRSIM_API ASkidVehiclePawn : public ASkidVehicle +class ASkidVehiclePawn : public AWheeledVehiclePawn { - GENERATED_BODY() - + GENERATED_BODY() + public: - ASkidVehiclePawn(); - - virtual void BeginPlay() override; - virtual void Tick(float Delta) override; - virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; - virtual void NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, - FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit) override; - - //interface - void initializeForBeginPlay(bool engine_sound); - const common_utils::UniqueValueMap getCameras() const; - PawnEvents* getPawnEvents() - { - return &pawn_events_; - } - USkidVehicleMovementComponent* getVehicleMovementComponent() const; - const msr::airlib::CarApiBase::CarControls& getKeyBoardControls() const - { - return keyboard_controls_; - } + ASkidVehiclePawn(); + + virtual void BeginPlay() override; + virtual void Tick(float Delta) override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + virtual void NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, + FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit) override; + + //interface + void initializeForBeginPlay(bool engine_sound); + const common_utils::UniqueValueMap getCameras() const; + PawnEvents* getPawnEvents() + { + return &pawn_events_; + } + UChaosVehicleMovementComponent* getVehicleMovementComponent() const; + USkeletalMeshComponent* getVehicleMesh() const; + const msr::airlib::CarApiBase::CarControls& getKeyBoardControls() const + { + return keyboard_controls_; + } + + UPROPERTY(BlueprintReadWrite, EditAnywhere) + float max_angular_velocity_ = 15; + + + UPROPERTY(BlueprintReadWrite, EditAnywhere) + float fixed_turn_rate_ = 0.1; + + UPROPERTY(BlueprintReadWrite, EditAnywhere) + bool stop_turn_ = false; private: - void updateHUDStrings(); - void updateInCarHUD(); - void updatePhysicsMaterial(); - - void setupInputBindings(); + void updateHUDStrings(); + void setupVehicleMovementComponent(); + void updateInCarHUD(); + void updatePhysicsMaterial(); + + void setupInputBindings(); + void onMoveForward(float Val); + void onMoveRight(float Val); + void onHandbrakePressed(); + void onHandbrakeReleased(); + void onFootBrake(float Val); + void onReversePressed(); + void onReverseReleased(); private: - typedef msr::airlib::AirSimSettings AirSimSettings; - - UClass* pip_camera_class_; - - PawnEvents pawn_events_; - - bool is_low_friction_; - UPhysicalMaterial* slippery_mat_; - UPhysicalMaterial* non_slippery_mat_; - - UPROPERTY() - USceneComponent* camera_front_center_base_; - UPROPERTY() - USceneComponent* camera_front_left_base_; - UPROPERTY() - USceneComponent* camera_front_right_base_; - UPROPERTY() - USceneComponent* camera_driver_base_; - UPROPERTY() - USceneComponent* camera_back_center_base_; - - UPROPERTY() - APIPCamera* camera_front_center_; - UPROPERTY() - APIPCamera* camera_front_left_; - UPROPERTY() - APIPCamera* camera_front_right_; - UPROPERTY() - APIPCamera* camera_driver_; - UPROPERTY() - APIPCamera* camera_back_center_; - - UTextRenderComponent* speed_text_render_; - UTextRenderComponent* gear_text_render_; - UAudioComponent* engine_sound_audio_; - - msr::airlib::CarApiBase::CarControls keyboard_controls_; - void onMoveX(float Val); - void onMoveY(float Val); - void onBreakPressed(); - void onBreakReleased(); - - FText last_speed_; - FText last_gear_; - FColor last_gear_display_color_; - FColor last_gear_display_reverse_color_; - UStaticMeshComponent* top_panel_component_; - bool show_top_panel_; + typedef msr::airlib::AirSimSettings AirSimSettings; + + UClass* pip_camera_class_; + + PawnEvents pawn_events_; + + bool is_low_friction_; + UPhysicalMaterial* slippery_mat_; + UPhysicalMaterial* non_slippery_mat_; + + UPROPERTY() + USceneComponent* camera_front_center_base_; + UPROPERTY() + USceneComponent* camera_front_left_base_; + UPROPERTY() + USceneComponent* camera_front_right_base_; + UPROPERTY() + USceneComponent* camera_driver_base_; + UPROPERTY() + USceneComponent* camera_back_center_base_; + + UPROPERTY() + APIPCamera* camera_front_center_; + UPROPERTY() + APIPCamera* camera_front_left_; + UPROPERTY() + APIPCamera* camera_front_right_; + UPROPERTY() + APIPCamera* camera_driver_; + UPROPERTY() + APIPCamera* camera_back_center_; + + UTextRenderComponent* speed_text_render_; + UTextRenderComponent* gear_text_render_; + UAudioComponent* engine_sound_audio_; + + msr::airlib::CarApiBase::CarControls keyboard_controls_; + + FText last_speed_; + FText last_gear_; + FColor last_gear_display_color_; + FColor last_gear_display_reverse_color_; }; diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnApi.cpp b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnApi.cpp index 2ab1329e7..226d8f125 100644 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnApi.cpp +++ b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnApi.cpp @@ -7,38 +7,94 @@ SkidVehiclePawnApi::SkidVehiclePawnApi(ASkidVehiclePawn* pawn, const msr::airlib::Kinematics::State* pawn_kinematics, msr::airlib::CarApiBase* vehicle_api) : pawn_(pawn), pawn_kinematics_(pawn_kinematics), vehicle_api_(vehicle_api) { - movement_ = pawn->GetSkidVehicleMovement(); + movement_ = CastChecked(pawn->GetVehicleMovement()); } void SkidVehiclePawnApi::updateMovement(const msr::airlib::CarApiBase::CarControls& controls) -{ - last_controls_ = controls; +{ + if (last_controls_.steering == 0 && controls.steering != 0) + turn_started_ = true; + if (last_controls_.throttle == 0 && controls.throttle != 0) + move_started_ = true; + if (last_controls_.steering != 0 && controls.steering == 0) + turn_completed_ = true; + if (last_controls_.throttle != 0 && controls.throttle == 0) + move_completed_ = true; - if (!controls.is_manual_gear && movement_->GetTargetGear() < 0) - movement_->SetTargetGear(0, true); //in auto gear we must have gear >= 0 - if (controls.is_manual_gear && movement_->GetTargetGear() != controls.manual_gear) - movement_->SetTargetGear(controls.manual_gear, controls.gear_immediate); + last_controls_ = controls; - movement_->SetYJoy(controls.throttle); - movement_->SetXJoy(controls.steering); - movement_->SetLeftBreak(controls.brake); - movement_->SetRightBreak(controls.brake); - if (controls.brake || controls.handbrake) { - movement_->SetBreaksOn(); - movement_->SetYJoy(0); - movement_->SetXJoy(0); + msr::airlib::CarApiBase::CarControls to_set_controls_ = controls; + to_set_controls_.brake = 0; + bool set_throttle = false; + bool set_steering = false; + if (controls.handbrake) { + to_set_controls_.throttle = 0; + to_set_controls_.steering = 0; + to_set_controls_.brake = 0; + to_set_controls_.handbrake = controls.handbrake; + set_throttle = true; + set_steering = true; } - else { - movement_->SetBreaksOff(); + else + { + if (move_completed_ || controls.throttle != 0){ + if (move_completed_) + set_throttle = true; + move_completed_ = false; + if (controls.throttle >= 0) { + to_set_controls_.brake = 0; + } + else { + to_set_controls_.brake = controls.throttle * -1.0f; + } + } + if (move_started_) { + move_started_ = false; + to_set_controls_.steering = 0; + to_set_controls_.throttle = 0; + set_throttle = true; + set_steering = true; + } + if (turn_started_) { + if (controls.throttle == 0) { + // For some reason ChaosVehicles when setting Yaw input with negative value requires a velocity on the vehicle + if((FMath::Abs(movement_->GetForwardSpeed() / 100)) < 0.02 && controls.steering > 0) { + to_set_controls_.throttle = pawn_->fixed_turn_rate_; + set_throttle = true; + } + } + } + if (controls.steering != 0 && pawn_->stop_turn_) { + to_set_controls_.steering = FMath::Lerp(controls.steering, 0, pawn_->fixed_turn_rate_); + UE_LOG(LogTemp, Warning, TEXT("STOP TURN")); + set_steering = true; + } + if (turn_completed_) { + to_set_controls_.steering = 0; + to_set_controls_.throttle = 0; + turn_completed_ = false; + set_throttle = true; + set_steering = true; + turn_started_ = false; + } + if (!set_steering) + { + to_set_controls_.steering = controls.steering; + set_steering = true; + } + if (!set_throttle) + { + to_set_controls_.throttle = controls.throttle; + set_throttle = true; + } } - movement_->SetUseAutomaticGears(!controls.is_manual_gear); - - //float accel = FMath::Min((float)sqrt(controls.steering * controls.steering + controls.throttle * controls.throttle), 1.0f); - //movement_->SetThrottleInput(accel); - //movement_->SetSteeringInput(controls.steering); - //movement_->SetBrakeInput(controls.brake); - //movement_->SetHandbrakeInput(controls.handbrake); - //movement_->SetUseAutomaticGears(!controls.is_manual_gear); + if(set_throttle) + movement_->SetThrottleInput(to_set_controls_.throttle); + if(set_steering) + movement_->SetYawInput(to_set_controls_.steering); + movement_->SetBrakeInput(to_set_controls_.brake); + movement_->SetHandbrakeInput(to_set_controls_.handbrake); + //UE_LOG(LogTemp, Warning, TEXT("throttle: %f | steering: %f | brake: %f | handbrake: %s"), to_set_controls_.throttle, to_set_controls_.steering, to_set_controls_.brake, to_set_controls_.handbrake ? TEXT("true") : TEXT("false")); } msr::airlib::CarApiBase::CarState SkidVehiclePawnApi::getCarState() const diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnApi.h b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnApi.h index 9311e0373..235775788 100644 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnApi.h +++ b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnApi.h @@ -3,7 +3,7 @@ #pragma once #include "vehicles/car/api/CarApiBase.hpp" -#include "SkidVehicleMovementComponent.h" +#include "ChaosWheeledVehicleMovementComponent.h" #include "physics/Kinematics.hpp" #include "SkidVehiclePawn.h" @@ -24,8 +24,12 @@ class SkidVehiclePawnApi { virtual ~SkidVehiclePawnApi(); private: - USkidVehicleMovementComponent* movement_; + UChaosWheeledVehicleMovementComponent* movement_; msr::airlib::CarApiBase::CarControls last_controls_; + bool turn_started_ = false; + bool move_started_ = false; + bool turn_completed_ = false; + bool move_completed_ = false; ASkidVehiclePawn* pawn_; const msr::airlib::Kinematics::State* pawn_kinematics_; msr::airlib::CarApiBase* vehicle_api_; diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnSimApi.h b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnSimApi.h index 37d199dbb..2b7c681f1 100644 --- a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnSimApi.h +++ b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidVehiclePawnSimApi.h @@ -3,8 +3,7 @@ #pragma once #include "CoreMinimal.h" -#include "SkidVehicleMovementComponent.h" - +#include "ChaosWheeledVehicleMovementComponent.h" #include "SkidVehiclePawn.h" #include "SkidVehiclePawnApi.h" #include "PawnEvents.h" diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidWheel.cpp b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidWheel.cpp new file mode 100644 index 000000000..9a4e355f1 --- /dev/null +++ b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidWheel.cpp @@ -0,0 +1,27 @@ +// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. + +#include "SkidWheel.h" +#include "UObject/ConstructorHelpers.h" + +USkidWheel::USkidWheel() +{ + WheelRadius = 17.667f; + WheelWidth = 38.0f; + WheelMass = 5.0f; + bAffectedByHandbrake = true; + bAffectedByBrake = true; + bAffectedByEngine = true; + bABSEnabled = true; + bTractionControlEnabled = false; + bAffectedBySteering = false; + MaxSteerAngle = 50.f; + AxleType = EAxleType::Undefined; + SlipThreshold = 100.0f; + SkidThreshold = 100.0f; + SuspensionForceOffset = FVector(0.0f, 0.0f, 0.0f); + SuspensionMaxRaise = 1.0f; + SuspensionMaxDrop = 1.0f; + SuspensionDampingRatio = 0.5f; + SpringRate = 100; + SuspensionSmoothing = 1; +} diff --git a/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidWheel.h b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidWheel.h new file mode 100644 index 000000000..668b23556 --- /dev/null +++ b/Unreal/Plugins/AirSim/Source/Vehicles/SkidSteer/SkidWheel.h @@ -0,0 +1,16 @@ +// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "ChaosVehicleWheel.h" +#include "SkidWheel.generated.h" + +UCLASS() +class USkidWheel : public UChaosVehicleWheel +{ + GENERATED_BODY() + +public: + USkidWheel(); +}; diff --git a/build.cmd b/build.cmd index 0f545dbd1..e578abe27 100644 --- a/build.cmd +++ b/build.cmd @@ -144,9 +144,9 @@ IF NOT EXIST Unreal\Plugins\AirSim\Content\VehicleAdv\SUV\v1.2.0 ( REM %powershell% -command "& { Start-BitsTransfer -Source https://github.com/Microsoft/AirSim/releases/download/v1.2.0/car_assets.zip -Destination suv_download_tmp\car_assets.zip }" REM %powershell% -command "& { (New-Object System.Net.WebClient).DownloadFile('https://github.com/Microsoft/AirSim/releases/download/v1.2.0/car_assets.zip', 'suv_download_tmp\car_assets.zip') }" if "%PWSHV7%" == "" ( - %powershell% -command "& { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; iwr https://github.com/CodexLabsLLC/Colosseum/releases/download/v2.0.0-beta.0/car_assets.zip -OutFile suv_download_tmp\car_assets.zip }" + %powershell% -command "& { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; iwr https://github.com/Cosys-Lab/Cosys-AirSim/releases/download/carassets/cosys_car_assets.zip -OutFile suv_download_tmp\car_assets.zip }" ) else ( - %powershell% -command "iwr https://github.com/CodexLabsLLC/Colosseum/releases/download/v2.0.0-beta.0/car_assets.zip -OutFile suv_download_tmp\car_assets.zip" + %powershell% -command "iwr https://github.com/Cosys-Lab/Cosys-AirSim/releases/download/carassets/cosys_car_assets.zip -OutFile suv_download_tmp\car_assets.zip" ) @echo off rmdir /S /Q Unreal\Plugins\AirSim\Content\VehicleAdv\SUV diff --git a/docs/skid_steer_vehicle.md b/docs/skid_steer_vehicle.md index 4c82a6583..6e270cd26 100644 --- a/docs/skid_steer_vehicle.md +++ b/docs/skid_steer_vehicle.md @@ -1,23 +1,18 @@ # Unreal Skid Steering Vehicle Model For vehicles that can't use the normal WheeledVehicle setup with normal steering wheels and non-steering wheels, but that use the skid-steering/differential steering (like a tank) an alternative vehicle model was created. -It is build using the NVIDIA PhysX Tank vehicle model. It is setup the same way as a WheeledVehicle and so can be easily be customized. +It is build using the Chaos engine of Unreal which does not support this vehicle type natively, as such, it can behave unrealistic at times. ![SkidSteerModel](http://www.robotplatform.com/knowledge/Classification_of_Robots/skid_steer_drive.png) http://www.robotplatform.com/knowledge/Classification_of_Robots/wheel_control_theory.html ## Creating a new skid steer vehicle -The steps to setup the vehicle are largely the same as a WheeledVehicle with some slight adjustments. -1. Follow [this guide](https://docs.unrealengine.com/en-US/Engine/Physics/Vehicles/VehicleUserGuide/index.html) to create the skeletal mesh, physics asset, wheel blueprint(s) and tire config data asset(s). -2. The animation blueprint is the exact same as in that tutorial however as class one should use the *SkidVehicleAnimInstance* sub-class. -3. For the vehicle blueprint to create the pawn it is also largely the same as in that tutorial however as class one should use the *SkidVehicle* sub-class. The vehicle setup parameters are more simplified. -4. For input relies on setting an X and Y(`SetXJoy()` and `SetYJoy()` functions, blueprint accessible!) value for a joystick. Hence it's always ideal to use a controller to steer the vehicle. - The steering model is based on [this guide](https://www.impulseadventure.com/elec/robot-differential-steering.html) with the following image as steering translation. Hence a X/Y input model is required. - -![ControllerModel](https://www.impulseadventure.com/elec/images/robot-diff-drive-joystick2.png) - -https://www.impulseadventure.com/elec/robot-differential-steering.html +The steps to setup the vehicle are largely the same as a WheeledVehiclePawn with some slight adjustments. +1. Follow [this guide](https://dev.epicgames.com/documentation/en-us/unreal-engine/how-to-set-up-vehicles-in-unreal-engine?application_version=5.2) to create the skeletal mesh and physics asset. +2. For the wheels setup, the vehicle should have 4 wheels, 2 for the left side and 2 for the right side. Please use SkidWheel as the wheel class. +3. For the vehicle blueprint to create the pawn it is also largely the same as in that tutorial however as class one should use the *SkidVehiclePawn* sub-class. The vehicle setup parameters are more simplified. +4. To have animated wheels, proper physics and correct steering behavior, please take a look at how the CPHusky is configured in the AirSim plugin. The Husky is a skid steer vehicle and can be used as a reference. ## Skid steer model within AirSim The skid steer model is a separate SimMode within AirSim. It is fully implemented in similar fashion as the normal Car SimMode. @@ -26,3 +21,5 @@ There are already two vehicle types implemented, the ClearPath Husky and Pioneer If you create a new vehicle using the Unreal skid steering vehicle model as described above, one can use the `PawnPaths` setting in the [Common Vehicle Settings in the settings.json file](settings.md#common-vehicle-setting) to link the custom vehicle pawn. ![Flamewheel](images/skidsteer_vehicles.png) + +Note that due to a bug in the ChaosVehicles and setting raw YawInput values when rotating on its axis to the left will cause a small forward movement as well. diff --git a/setup.sh b/setup.sh index 896a475ca..f4f6688b1 100755 --- a/setup.sh +++ b/setup.sh @@ -158,7 +158,7 @@ if $downloadHighPolySuv; then fi mkdir -p "suv_download_tmp" cd suv_download_tmp - wget https://github.com/CodexLabsLLC/Colosseum/releases/download/v2.0.0-beta.0/car_assets.zip + wget https://github.com/Cosys-Lab/Cosys-AirSim/releases/download/carassets/cosys_car_assets.zip if [ -d "../Unreal/Plugins/AirSim/Content/VehicleAdv/SUV" ]; then rm -rf "../Unreal/Plugins/AirSim/Content/VehicleAdv/SUV" fi