diff --git a/UE4Project/.gitignore b/UE4Project/.gitignore index 771741f4..046489ed 100644 --- a/UE4Project/.gitignore +++ b/UE4Project/.gitignore @@ -1,3 +1,6 @@ +# Rider IDE +.idea/ + # don't check-in generated files *.sln *_BuiltData.uasset diff --git a/UE4Project/.ignore b/UE4Project/.ignore new file mode 100644 index 00000000..6af96eab --- /dev/null +++ b/UE4Project/.ignore @@ -0,0 +1,7 @@ +/.vscode +/Saved +/Intermediate +/.idea +/Content +/Plugins/AirSim/Intermediate +/Plugins/AirSim/Content diff --git a/UE4Project/FSOnline.uproject b/UE4Project/FSOnline.uproject index a483f897..818a954e 100644 --- a/UE4Project/FSOnline.uproject +++ b/UE4Project/FSOnline.uproject @@ -1,6 +1,6 @@ { "FileVersion": 3, - "EngineAssociation": "4.27", + "EngineAssociation": "{39102460-AC08-4665-97C6-39E7243134BA}", "Category": "", "Description": "", "Modules": [ diff --git a/UE4Project/Plugins/AirSim/AirSim.uplugin b/UE4Project/Plugins/AirSim/AirSim.uplugin index bbbf5cc8..a04a345a 100644 --- a/UE4Project/Plugins/AirSim/AirSim.uplugin +++ b/UE4Project/Plugins/AirSim/AirSim.uplugin @@ -23,7 +23,7 @@ ], "Plugins": [ { - "Name": "PhysXVehicles", + "Name": "ChaosVehiclesPlugin", "Enabled": true } ] diff --git a/UE4Project/Plugins/AirSim/Source/AirBlueprintLib.cpp b/UE4Project/Plugins/AirSim/Source/AirBlueprintLib.cpp index 4a5c749f..ee4fe252 100644 --- a/UE4Project/Plugins/AirSim/Source/AirBlueprintLib.cpp +++ b/UE4Project/Plugins/AirSim/Source/AirBlueprintLib.cpp @@ -3,7 +3,6 @@ #include "AirBlueprintLib.h" #include "GameFramework/WorldSettings.h" -#include "Components/SceneCaptureComponent2D.h" #include "Components/SkinnedMeshComponent.h" #include "GameFramework/RotatingMovementComponent.h" #include "Components/StaticMeshComponent.h" @@ -11,15 +10,15 @@ #include "Runtime/Engine/Classes/Engine/StaticMesh.h" #include "UObject/UObjectIterator.h" #include "Camera/CameraComponent.h" -//#include "Runtime/Foliage/Public/FoliageType.h" #include "Misc/MessageDialog.h" #include "Engine/LocalPlayer.h" #include "Engine/SkeletalMesh.h" -#include "Slate/SceneViewport.h" #include "IImageWrapper.h" #include "Misc/ObjectThumbnail.h" #include "Engine/Engine.h" #include + +#include "IImageWrapperModule.h" #include "common/common_utils/Utils.hpp" /* @@ -398,9 +397,9 @@ std::vector UAirBlueprintLib::Ge ENQUEUE_RENDER_COMMAND(GetVertexBuffer)( [vertex_buffer, data](FRHICommandListImmediate& RHICmdList) { - FVector* indices = (FVector*)RHILockVertexBuffer(vertex_buffer->VertexBufferRHI, 0, vertex_buffer->VertexBufferRHI->GetSize(), RLM_ReadOnly); + FVector* indices = (FVector*)RHILockBuffer(vertex_buffer->VertexBufferRHI, 0, vertex_buffer->VertexBufferRHI->GetSize(), RLM_ReadOnly); memcpy(data, indices, vertex_buffer->VertexBufferRHI->GetSize()); - RHIUnlockVertexBuffer(vertex_buffer->VertexBufferRHI); + RHIUnlockBuffer(vertex_buffer->VertexBufferRHI); }); FStaticMeshLODResources& lod = comp->GetStaticMesh()->GetRenderData()->LODResources[0]; @@ -416,9 +415,9 @@ std::vector UAirBlueprintLib::Ge ENQUEUE_RENDER_COMMAND(GetIndexBuffer)( [IndexBuffer, data_ptr](FRHICommandListImmediate& RHICmdList) { - uint16_t* indices = (uint16_t*)RHILockIndexBuffer(IndexBuffer->IndexBufferRHI, 0, IndexBuffer->IndexBufferRHI->GetSize(), RLM_ReadOnly); + uint16_t* indices = (uint16_t*)RHILockBuffer(IndexBuffer->IndexBufferRHI, 0, IndexBuffer->IndexBufferRHI->GetSize(), RLM_ReadOnly); memcpy(data_ptr, indices, IndexBuffer->IndexBufferRHI->GetSize()); - RHIUnlockIndexBuffer(IndexBuffer->IndexBufferRHI); + RHIUnlockBuffer(IndexBuffer->IndexBufferRHI); }); //Need to force the render command to go through cause on the next iteration the buffer no longer exists @@ -439,9 +438,9 @@ std::vector UAirBlueprintLib::Ge ENQUEUE_RENDER_COMMAND(GetIndexBuffer)( [IndexBuffer, data_ptr](FRHICommandListImmediate& RHICmdList) { - uint32_t* indices = (uint32_t*)RHILockIndexBuffer(IndexBuffer->IndexBufferRHI, 0, IndexBuffer->IndexBufferRHI->GetSize(), RLM_ReadOnly); + uint32_t* indices = (uint32_t*)RHILockBuffer(IndexBuffer->IndexBufferRHI, 0, IndexBuffer->IndexBufferRHI->GetSize(), RLM_ReadOnly); memcpy(data_ptr, indices, IndexBuffer->IndexBufferRHI->GetSize()); - RHIUnlockIndexBuffer(IndexBuffer->IndexBufferRHI); + RHIUnlockBuffer(IndexBuffer->IndexBufferRHI); }); FlushRenderingCommands(); diff --git a/UE4Project/Plugins/AirSim/Source/AirBlueprintLib.h b/UE4Project/Plugins/AirSim/Source/AirBlueprintLib.h index f43a0045..18d18af3 100644 --- a/UE4Project/Plugins/AirSim/Source/AirBlueprintLib.h +++ b/UE4Project/Plugins/AirSim/Source/AirBlueprintLib.h @@ -8,9 +8,7 @@ #include "Misc/MessageDialog.h" #include "Components/InputComponent.h" #include "GameFramework/PlayerInput.h" -#include "IImageWrapperModule.h" #include "Kismet/BlueprintFunctionLibrary.h" -#include "Kismet/KismetMathLibrary.h" #include "Components/MeshComponent.h" #include "LandscapeProxy.h" #include "Kismet/GameplayStatics.h" @@ -123,7 +121,7 @@ class UAirBlueprintLib : public UBlueprintFunctionLibrary template static FInputActionBinding& BindActionToKey(const FName action_name, const FKey in_key, UserClass* actor, - typename FInputActionHandlerSignature::TUObjectMethodDelegate< UserClass >::FMethodPtr func, bool on_press_or_release = false, + FInputActionHandlerSignature::TMethodPtr func, bool on_press_or_release = false, bool shift_key = false, bool control_key = false, bool alt_key = false, bool command_key = false) { FInputActionKeyMapping action(action_name, in_key, shift_key, control_key, alt_key, command_key); @@ -137,7 +135,7 @@ class UAirBlueprintLib : public UBlueprintFunctionLibrary template static FInputAxisBinding& BindAxisToKey(const FName axis_name, const FKey in_key, AActor* actor, UserClass* obj, - typename FInputAxisHandlerSignature::TUObjectMethodDelegate::FMethodPtr func) + FInputAxisHandlerSignature::TMethodPtr func) { FInputAxisKeyMapping axis(axis_name, in_key); @@ -146,7 +144,7 @@ class UAirBlueprintLib : public UBlueprintFunctionLibrary template static FInputAxisBinding& BindAxisToKey(const FInputAxisKeyMapping& axis, AActor* actor, UserClass* obj, - typename FInputAxisHandlerSignature::TUObjectMethodDelegate::FMethodPtr func) + typename FInputAxisHandlerSignature::TMethodPtr func) { APlayerController* controller = actor->GetWorld()->GetFirstPlayerController(); diff --git a/UE4Project/Plugins/AirSim/Source/AirSim.Build.cs b/UE4Project/Plugins/AirSim/Source/AirSim.Build.cs index bd19995b..c5a0c701 100644 --- a/UE4Project/Plugins/AirSim/Source/AirSim.Build.cs +++ b/UE4Project/Plugins/AirSim/Source/AirSim.Build.cs @@ -75,8 +75,19 @@ public AirSim(ReadOnlyTargetRules Target) : base(Target) bEnableExceptions = true; - PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "HTTP", "InputCore", "ImageWrapper", "RenderCore", "RHI", "PhysXVehicles", "PhysicsCore", "PhysXVehicleLib", "PhysX", "APEX", "Landscape" }); - PrivateDependencyModuleNames.AddRange(new string[] { "UMG", "Slate", "SlateCore" }); + PublicDependencyModuleNames.AddRange(new string[] { + "Core", + "CoreUObject", + "Engine", + "HTTP", + "InputCore", + "ImageWrapper", + "RenderCore", + "RHI", + "ChaosVehicles", + "Landscape" + }); + PrivateDependencyModuleNames.AddRange(new string[] { "UMG", "Slate", "SlateCore", "RenderCore" }); //suppress VC++ proprietary warnings PublicDefinitions.Add("_SCL_SECURE_NO_WARNINGS=1"); diff --git a/UE4Project/Plugins/AirSim/Source/AirSim.cpp b/UE4Project/Plugins/AirSim/Source/AirSim.cpp index 37d4511d..1a5eaa91 100644 --- a/UE4Project/Plugins/AirSim/Source/AirSim.cpp +++ b/UE4Project/Plugins/AirSim/Source/AirSim.cpp @@ -1,26 +1,26 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "AirSim.h" -#include "Misc/Paths.h" -#include "Modules/ModuleManager.h" -#include "Modules/ModuleInterface.h" - -class FAirSim : public IModuleInterface -{ - virtual void StartupModule() override; - virtual void ShutdownModule() override; -}; - -IMPLEMENT_MODULE(FAirSim, AirSim) - -void FAirSim::StartupModule() -{ - //plugin startup - UE_LOG(LogTemp, Log, TEXT("StartupModule: AirSim plugin")); -} - -void FAirSim::ShutdownModule() -{ - //plugin shutdown +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "AirSim.h" +#include "Misc/Paths.h" +#include "Modules/ModuleManager.h" +#include "Modules/ModuleInterface.h" + +class FAirSim : public IModuleInterface +{ + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; + +IMPLEMENT_MODULE(FAirSim, AirSim) + +void FAirSim::StartupModule() +{ + //plugin startup + UE_LOG(LogTemp, Log, TEXT("StartupModule: AirSim plugin")); +} + +void FAirSim::ShutdownModule() +{ + //plugin shutdown } \ No newline at end of file diff --git a/UE4Project/Plugins/AirSim/Source/Referee.cpp b/UE4Project/Plugins/AirSim/Source/Referee.cpp index 7f65ce24..2e7283ce 100644 --- a/UE4Project/Plugins/AirSim/Source/Referee.cpp +++ b/UE4Project/Plugins/AirSim/Source/Referee.cpp @@ -1,80 +1,80 @@ -// This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as published by the Free Software Foundation - -#include "Referee.h" - - -// Sets default values -AReferee::AReferee() -{ - // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. - PrimaryActorTick.bCanEverTick = true; - -} - -// Called when the game starts or when spawned -void AReferee::BeginPlay() -{ - Super::BeginPlay(); - -} - -msr::airlib::CarApiBase::RefereeState AReferee::getState() { - return this->state; -} - -// Called every frame -void AReferee::Tick(float DeltaTime) -{ - Super::Tick(DeltaTime); - -} - -int32 AReferee::ConeHit(FString coneName) -{ - return (int32) (++state.doo_counter); -} - -int32 AReferee::LapCompleted(float lapTime) -{ - state.laps.push_back(lapTime); - return state.laps.size(); -} - -void AReferee::AppendYellowCone(FTransform transform) { - msr::airlib::CarApiBase::Cone cone; - cone.location.x = transform.GetTranslation().X; - cone.location.y = transform.GetTranslation().Y; - cone.color = msr::airlib::CarApiBase::ConeColor::Yellow; - state.cones.push_back(cone); -} - -void AReferee::AppendBlueCone(FTransform transform) { - msr::airlib::CarApiBase::Cone cone; - cone.location.x = transform.GetTranslation().X; - cone.location.y = transform.GetTranslation().Y; - cone.color = msr::airlib::CarApiBase::ConeColor::Blue; - state.cones.push_back(cone); -} - -void AReferee::AppendBigOrangeCone(FTransform transform){ - msr::airlib::CarApiBase::Cone cone; - cone.location.x = transform.GetTranslation().X; - cone.location.y = transform.GetTranslation().Y; - cone.color = msr::airlib::CarApiBase::ConeColor::OrangeLarge; - state.cones.push_back(cone); -} - -void AReferee::AppendSmallOrangeCone(FTransform transform){ - msr::airlib::CarApiBase::Cone cone; - cone.location.x = transform.GetTranslation().X; - cone.location.y = transform.GetTranslation().Y; - cone.color = msr::airlib::CarApiBase::ConeColor::OrangeSmall; - state.cones.push_back(cone); -} - -void AReferee::LoadStartPos(FVector pos) { - msr::airlib::CarApiBase::Point2D point; - point.x = pos.X; - point.y = pos.Y; - state.car_start_location = point; +// This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as published by the Free Software Foundation + +#include "Referee.h" + + +// Sets default values +AReferee::AReferee() +{ + // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; + +} + +// Called when the game starts or when spawned +void AReferee::BeginPlay() +{ + Super::BeginPlay(); + +} + +msr::airlib::CarApiBase::RefereeState AReferee::getState() { + return this->state; +} + +// Called every frame +void AReferee::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); + +} + +int32 AReferee::ConeHit(FString coneName) +{ + return (int32) (++state.doo_counter); +} + +int32 AReferee::LapCompleted(float lapTime) +{ + state.laps.push_back(lapTime); + return state.laps.size(); +} + +void AReferee::AppendYellowCone(FTransform transform) { + msr::airlib::CarApiBase::Cone cone; + cone.location.x = transform.GetTranslation().X; + cone.location.y = transform.GetTranslation().Y; + cone.color = msr::airlib::CarApiBase::ConeColor::Yellow; + state.cones.push_back(cone); +} + +void AReferee::AppendBlueCone(FTransform transform) { + msr::airlib::CarApiBase::Cone cone; + cone.location.x = transform.GetTranslation().X; + cone.location.y = transform.GetTranslation().Y; + cone.color = msr::airlib::CarApiBase::ConeColor::Blue; + state.cones.push_back(cone); +} + +void AReferee::AppendBigOrangeCone(FTransform transform){ + msr::airlib::CarApiBase::Cone cone; + cone.location.x = transform.GetTranslation().X; + cone.location.y = transform.GetTranslation().Y; + cone.color = msr::airlib::CarApiBase::ConeColor::OrangeLarge; + state.cones.push_back(cone); +} + +void AReferee::AppendSmallOrangeCone(FTransform transform){ + msr::airlib::CarApiBase::Cone cone; + cone.location.x = transform.GetTranslation().X; + cone.location.y = transform.GetTranslation().Y; + cone.color = msr::airlib::CarApiBase::ConeColor::OrangeSmall; + state.cones.push_back(cone); +} + +void AReferee::LoadStartPos(FVector pos) { + msr::airlib::CarApiBase::Point2D point; + point.x = pos.X; + point.y = pos.Y; + state.car_start_location = point; } \ No newline at end of file diff --git a/UE4Project/Plugins/AirSim/Source/Referee.h b/UE4Project/Plugins/AirSim/Source/Referee.h index 2cc4e257..82eb6f5d 100644 --- a/UE4Project/Plugins/AirSim/Source/Referee.h +++ b/UE4Project/Plugins/AirSim/Source/Referee.h @@ -1,51 +1,51 @@ -// This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as published by the Free Software Foundation - -#pragma once - -#include "CoreMinimal.h" -#include "GameFramework/Actor.h" -#include "vehicles/car/api/CarApiBase.hpp" -#include "Referee.generated.h" - -UCLASS() -class AIRSIM_API AReferee : public AActor -{ - GENERATED_BODY() - -public: - // Sets default values for this actor's properties - AReferee(); - - msr::airlib::CarApiBase::RefereeState getState(); - -protected: - // Called when the game starts or when spawned - virtual void BeginPlay() override; - msr::airlib::CarApiBase::RefereeState state; - -public: - // Called every frame - virtual void Tick(float DeltaTime) override; - - - UFUNCTION(BlueprintCallable, Category="Referee") - int32 ConeHit(FString coneName); - - UFUNCTION(BlueprintCallable, Category="Referee") - int32 LapCompleted(float lapTime); - - UFUNCTION(BlueprintCallable, Category="Referee") - void AppendYellowCone(FTransform cone); - - UFUNCTION(BlueprintCallable, Category="Referee") - void AppendBlueCone(FTransform cone); - - UFUNCTION(BlueprintCallable, Category="Referee") - void AppendBigOrangeCone(FTransform cone); - - UFUNCTION(BlueprintCallable, Category="Referee") - void AppendSmallOrangeCone(FTransform cone); - - UFUNCTION(BlueprintCallable, Category="Referee") - void LoadStartPos(FVector pos); -}; +// This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as published by the Free Software Foundation + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/Actor.h" +#include "vehicles/car/api/CarApiBase.hpp" +#include "Referee.generated.h" + +UCLASS() +class AIRSIM_API AReferee : public AActor +{ + GENERATED_BODY() + +public: + // Sets default values for this actor's properties + AReferee(); + + msr::airlib::CarApiBase::RefereeState getState(); + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + msr::airlib::CarApiBase::RefereeState state; + +public: + // Called every frame + virtual void Tick(float DeltaTime) override; + + + UFUNCTION(BlueprintCallable, Category="Referee") + int32 ConeHit(FString coneName); + + UFUNCTION(BlueprintCallable, Category="Referee") + int32 LapCompleted(float lapTime); + + UFUNCTION(BlueprintCallable, Category="Referee") + void AppendYellowCone(FTransform cone); + + UFUNCTION(BlueprintCallable, Category="Referee") + void AppendBlueCone(FTransform cone); + + UFUNCTION(BlueprintCallable, Category="Referee") + void AppendBigOrangeCone(FTransform cone); + + UFUNCTION(BlueprintCallable, Category="Referee") + void AppendSmallOrangeCone(FTransform cone); + + UFUNCTION(BlueprintCallable, Category="Referee") + void LoadStartPos(FVector pos); +}; diff --git a/UE4Project/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp b/UE4Project/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp index 54b317a5..b9139dec 100644 --- a/UE4Project/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp +++ b/UE4Project/Plugins/AirSim/Source/SimJoyStick/SimJoyStick.cpp @@ -1,424 +1,424 @@ -#include "SimJoyStick.h" - -#if defined _WIN32 || defined _WIN64 - -#include "DirectInputJoystick.h" - -struct SimJoyStick::impl { -public: - void getJoyStickState(int index, SimJoyStick::State& state, const AxisMaps& maps) - { - if (index >= kMaxControllers) { - state.is_initialized = false; - return; - } - - if (controllers_[index] == nullptr) { - controllers_[index].reset(new DirectInputJoyStick()); - if (!controllers_[index]->initialize(index)) { - state.is_initialized = false; - state.message = controllers_[index]->getState(false).message; - return; - } - state.is_initialized = true; - } - - const DirectInputJoyStick::JoystickState& di_state = controllers_[index]->getState(); - const DirectInputJoyStick::JoystickInfo& joystick_info = controllers_[index]->getJoystickInfo(); - - state.is_valid = di_state.is_valid; - - state.left_x = getAxisValue(AxisMap::AxisType::LeftX, maps.left_x, di_state, joystick_info.pid_vid); - state.left_y = getAxisValue(AxisMap::AxisType::LeftY, maps.left_y, di_state, joystick_info.pid_vid); - state.right_x = getAxisValue(AxisMap::AxisType::RightX, maps.right_x, di_state, joystick_info.pid_vid); - state.right_y = getAxisValue(AxisMap::AxisType::RightY, maps.right_y, di_state, joystick_info.pid_vid); - state.right_z = getAxisValue(AxisMap::AxisType::RightZ, maps.right_z, di_state, joystick_info.pid_vid); - state.left_z = getAxisValue(AxisMap::AxisType::LeftZ, maps.left_z, di_state, joystick_info.pid_vid); - - state.slider0 = static_cast(di_state.slider0); - state.slider1 = static_cast(di_state.slider1); - - state.pov0 = static_cast(di_state.pov0); - state.pov1 = static_cast(di_state.pov1); - state.pov2 = static_cast(di_state.pov2); - state.pov3 = static_cast(di_state.pov3); - - state.pid_vid = joystick_info.pid_vid; - - state.buttons = 0; - for (int i = 0; i < sizeof(int)*8; ++i) { - state.buttons |= ((di_state.buttons[i] & 0x80) == 0 ? 0 : 1) << i; - } - } - - void setAutoCenter(int index, double strength) { - if (index >= 0) - controllers_[index]->setAutoCenter(strength); - } - - void setWheelRumble(int index, double strength) { - if (index >= 0) - controllers_[index]->setWheelRumble(strength); - } - - -private: - float getMappedValue(AxisMap::AxisType axis_type, const AxisMap& map, const DirectInputJoyStick::JoystickState& di_state, const std::string& device_pid_vid) - { - AxisMap::AxisType rc_axis; - if (map.rc_axis == AxisMap::AxisType::Auto) { - if (device_pid_vid == "" || device_pid_vid == "VID_0483&PID_5710") { //RCs like FrSky Taranis - switch (axis_type) { - case AxisMap::AxisType::LeftX: rc_axis = AxisMap::AxisType::RightX; break; - case AxisMap::AxisType::LeftY: rc_axis = AxisMap::AxisType::LeftX; break; - case AxisMap::AxisType::LeftZ: rc_axis = AxisMap::AxisType::RightY; break; - case AxisMap::AxisType::RightX: rc_axis = AxisMap::AxisType::LeftY; break; - case AxisMap::AxisType::RightY: rc_axis = AxisMap::AxisType::LeftZ; break; - case AxisMap::AxisType::RightZ: rc_axis = AxisMap::AxisType::RightZ; break; - default: - throw std::invalid_argument("Unsupported axis_type in getMappedValue"); - } - } - else if (device_pid_vid == "VID_0401&PID_0401") { //Flysky FS-SM100 RC USB adapter - switch (axis_type) { - case AxisMap::AxisType::LeftX: rc_axis = AxisMap::AxisType::RightY; break; - case AxisMap::AxisType::LeftY: rc_axis = AxisMap::AxisType::LeftX; break; - case AxisMap::AxisType::LeftZ: rc_axis = AxisMap::AxisType::RightX; break; - case AxisMap::AxisType::RightX: rc_axis = AxisMap::AxisType::LeftY; break; - case AxisMap::AxisType::RightY: rc_axis = AxisMap::AxisType::LeftZ; break; - case AxisMap::AxisType::RightZ: rc_axis = AxisMap::AxisType::RightZ; break; - default: - throw std::invalid_argument("Unsupported axis_type in getMappedValue"); - } - } - else { //Xbox controllers - rc_axis = axis_type; - } - } - else - rc_axis = map.rc_axis; - - long result; - switch (rc_axis) - { - case AxisMap::AxisType::LeftX: result = di_state.x; break; - case AxisMap::AxisType::LeftY: result = di_state.y; break; - case AxisMap::AxisType::LeftZ: result = di_state.z; break; - case AxisMap::AxisType::RightX: result = di_state.rx; break; - case AxisMap::AxisType::RightY: result = di_state.ry; break; - case AxisMap::AxisType::RightZ: result = di_state.rz; break; - default: - throw std::invalid_argument("Unsupported rc_axis in getMappedValue"); - } - - return static_cast(result); - } - - float getAxisValue(AxisMap::AxisType axis_type, const AxisMap& map, const DirectInputJoyStick::JoystickState& di_state, const std::string& device_pid_vid) - { - float val = getMappedValue(axis_type, map, di_state, device_pid_vid); - - //normalize min to max --> 0 to 1 - val = (val - map.min_val) / (map.max_val - map.min_val); - - switch (map.direction) - { - case AxisMap::AxisDirection::Auto: - if ( - ((device_pid_vid == "" || device_pid_vid == "VID_0483&PID_5710") && - (axis_type == AxisMap::AxisType::LeftZ || axis_type == AxisMap::AxisType::RightY)) || - ((device_pid_vid != "" && device_pid_vid != "VID_0483&PID_5710" && device_pid_vid != "VID_0401&PID_0401") && - (axis_type == AxisMap::AxisType::LeftY)) - ) - val = 1 - val; - break; - case AxisMap::AxisDirection::Normal: break; - case AxisMap::AxisDirection::Reverse: val = 1 - val; break; - default: - throw std::invalid_argument("Unsupported map.direction in getAxisValue"); - } - - //normalize 0 to 1 --> -1 to 1 - val = 2*val - 1; - - return val; - } - -private: - static constexpr unsigned int kMaxControllers = 4; - std::unique_ptr controllers_[kMaxControllers]; -}; - -#else - -#include -#include -#include -#include -#include -#include -//#include -#include "unistd.h" - -//implementation for unsupported OS -struct SimJoyStick::impl { -private: - - - - class JoystickEvent - { - public: - /** Minimum value of axes range */ - static const short MIN_AXES_VALUE = -32768; - - /** Maximum value of axes range */ - static const short MAX_AXES_VALUE = 32767; - - /** - * The timestamp of the event, in milliseconds. - */ - unsigned int time; - - /** - * The value associated with this joystick event. - * For buttons this will be either 1 (down) or 0 (up). - * For axes, this will range between MIN_AXES_VALUE and MAX_AXES_VALUE. - */ - short value; - - /** - * The event type. - */ - unsigned char type; - - /** - * The axis/button number. - */ - unsigned char number; - - /** - * Returns true if this event is the result of a button press. - */ - bool isButton() - { - static constexpr unsigned char JS_EVENT_BUTTON = 0x01; // button pressed/released - return (type & JS_EVENT_BUTTON) != 0; - } - - /** - * Returns true if this event is the result of an axis movement. - */ - bool isAxis() - { - static constexpr unsigned char JS_EVENT_AXIS = 0x02; // joystick moved - return (type & JS_EVENT_AXIS) != 0; - } - - /** - * Returns true if this event is part of the initial state obtained when - * the joystick is first connected to. - */ - bool isInitialState() - { - static constexpr unsigned char JS_EVENT_INIT = 0x80; // initial state of device - return (type & JS_EVENT_INIT) != 0; - } - - /** - * The ostream inserter needs to be a friend so it can access the - * internal data structures. - */ - friend std::ostream& operator<<(std::ostream& os, const JoystickEvent& e); - }; - - -public: - ~impl() - { - if (fd_ >= 0) - close(fd_); - } - - static float normalizeAxisVal(int axis_val, bool wide, bool zero2One, bool reversed) - { - float min_val = wide ? -32768 : -16384; - float max_val = wide ? 32767 : 16383; - - float val = (axis_val - min_val) / (max_val - min_val); - if (zero2One) { - if (reversed) - val = 1 - val; - } - else { - val = 2*val - 1; - if (reversed) - val *= -1; - } - - return val; - } - - void getJoyStickState(int index, SimJoyStick::State& state, const AxisMaps& maps) - { - unused(maps); - - static constexpr bool blocking = false; - - //if this is new index - if (index != last_index_) { - //getJoystickInfo(1, manufacturerID, productID, state.message); - - //close previous one - if (fd_ >= 0) - close(fd_); - - //open new device - std::stringstream devicePath; - devicePath << "/dev/input/js" << index; - - fd_ = open(devicePath.str().c_str(), blocking ? O_RDONLY : O_RDONLY | O_NONBLOCK); - state.is_initialized = fd_ >= 0; - last_index_ = index; - } - - //if open was successful - if (fd_ >= 0) { - //read the device - int bytes = read(fd_, &event_, sizeof(event_)); - - //if we didn't had valid read - if (bytes == -1 || bytes != sizeof(event_)) { - // NOTE if this condition is not met, we're probably out of sync and this - // Joystick instance is likely unusable - //TODO: set below to false? - //state.is_valid = false; - } - else { - state.is_valid = true; - - if (event_.isButton()) { - if (event_.value == 0) - state.buttons &= ~(1 << event_.number); - else - state.buttons |= (1 << event_.number); - } - else if (event_.isAxis()) { - if (device_type > 0) { //RCs like FrSky Taranis - switch(event_.number) { - case 0: state.left_y = event_.value; break; - case 1: state.right_x = event_.value; break; - case 2: state.right_y = event_.value; break; - case 3: state.left_x = event_.value; break; - default: break; - } - } - else { //XBox - switch(event_.number) { - case 0: state.left_x = normalizeAxisVal(event_.value, true, false, false); break; - case 1: state.left_y = normalizeAxisVal(event_.value, false, true, true); break; - case 2: state.left_z = normalizeAxisVal(event_.value, true, false, false); break; - case 3: state.right_x = normalizeAxisVal(event_.value, true, false, false); break; - case 4: state.right_y = normalizeAxisVal(event_.value, true, false, false); break; - case 5: state.right_z = normalizeAxisVal(event_.value, true, false, false); break; - - default: break; - } - } - } - //else ignore - } - } - else - state.is_valid = false; - } - - - void setAutoCenter(unsigned int index, double strength) { - unused(index); - unused(strength); - //TODO: implement this for linux - } - - void setWheelRumble(unsigned int index, double strength) { - unused(index); - unused(strength); - //TODO: implement this for linux - } - - // bool getJoystickInfo(int index, std::string& manufacturerID, std::string& productID, std::string& message) - // { - // manufacturerID = productID = ""; - // // Use udev to look up the product and manufacturer IDs - // struct udev *udev = udev_new(); - // if (udev) { - // char sysname[32]; - // std::snprintf(sysname, sizeof(sysname), "js%u", index); - // struct udev_device *dev = udev_device_new_from_subsystem_sysname(udev, "input", sysname); - // dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); - // if (!dev) - // { - // message = "Unable to find parent USB device"; - // return false; - // } - - // std::stringstream ss; - // ss << std::hex << udev_device_get_sysattr_value(dev, "idVendor"); - // ss >> manufacturerID; - - // ss.clear(); - // ss.str(""); - // ss << std::hex << udev_device_get_sysattr_value(dev, "idProduct"); - // ss >> productID; - - // udev_device_unref(dev); - // } - // else - // { - // message = "Cannot create udev"; - // return false; - // } - // udev_unref(udev); - // return true; - // } - -private: - int last_index_ = -1; - int fd_ = -1; - JoystickEvent event_; - std::string manufacturerID, productID; - int device_type = 0; -}; - -#endif - -SimJoyStick::SimJoyStick() -{ - pimpl_.reset(new impl()); -} -SimJoyStick::~SimJoyStick() -{ - //required for pimpl -} - -void SimJoyStick::getJoyStickState(int index, SimJoyStick::State& state) const -{ - if (index < 0) { - state.is_initialized = false; - state.is_valid = false; - return; - } - - //TODO: anyway to workaround const_cast? - const_cast(this)->pimpl_->getJoyStickState(index, state, axis_maps); -} - -void SimJoyStick::setAutoCenter(int index, double strength) -{ - pimpl_->setAutoCenter(index, strength); -} - -void SimJoyStick::setWheelRumble(int index, double strength) -{ - pimpl_->setWheelRumble(index, strength); +#include "SimJoyStick.h" + +#if defined _WIN32 || defined _WIN64 + +#include "DirectInputJoystick.h" + +struct SimJoyStick::impl { +public: + void getJoyStickState(int index, SimJoyStick::State& state, const AxisMaps& maps) + { + if (index >= kMaxControllers) { + state.is_initialized = false; + return; + } + + if (controllers_[index] == nullptr) { + controllers_[index].reset(new DirectInputJoyStick()); + if (!controllers_[index]->initialize(index)) { + state.is_initialized = false; + state.message = controllers_[index]->getState(false).message; + return; + } + state.is_initialized = true; + } + + const DirectInputJoyStick::JoystickState& di_state = controllers_[index]->getState(); + const DirectInputJoyStick::JoystickInfo& joystick_info = controllers_[index]->getJoystickInfo(); + + state.is_valid = di_state.is_valid; + + state.left_x = getAxisValue(AxisMap::AxisType::LeftX, maps.left_x, di_state, joystick_info.pid_vid); + state.left_y = getAxisValue(AxisMap::AxisType::LeftY, maps.left_y, di_state, joystick_info.pid_vid); + state.right_x = getAxisValue(AxisMap::AxisType::RightX, maps.right_x, di_state, joystick_info.pid_vid); + state.right_y = getAxisValue(AxisMap::AxisType::RightY, maps.right_y, di_state, joystick_info.pid_vid); + state.right_z = getAxisValue(AxisMap::AxisType::RightZ, maps.right_z, di_state, joystick_info.pid_vid); + state.left_z = getAxisValue(AxisMap::AxisType::LeftZ, maps.left_z, di_state, joystick_info.pid_vid); + + state.slider0 = static_cast(di_state.slider0); + state.slider1 = static_cast(di_state.slider1); + + state.pov0 = static_cast(di_state.pov0); + state.pov1 = static_cast(di_state.pov1); + state.pov2 = static_cast(di_state.pov2); + state.pov3 = static_cast(di_state.pov3); + + state.pid_vid = joystick_info.pid_vid; + + state.buttons = 0; + for (int i = 0; i < sizeof(int)*8; ++i) { + state.buttons |= ((di_state.buttons[i] & 0x80) == 0 ? 0 : 1) << i; + } + } + + void setAutoCenter(int index, double strength) { + if (index >= 0) + controllers_[index]->setAutoCenter(strength); + } + + void setWheelRumble(int index, double strength) { + if (index >= 0) + controllers_[index]->setWheelRumble(strength); + } + + +private: + float getMappedValue(AxisMap::AxisType axis_type, const AxisMap& map, const DirectInputJoyStick::JoystickState& di_state, const std::string& device_pid_vid) + { + AxisMap::AxisType rc_axis; + if (map.rc_axis == AxisMap::AxisType::Auto) { + if (device_pid_vid == "" || device_pid_vid == "VID_0483&PID_5710") { //RCs like FrSky Taranis + switch (axis_type) { + case AxisMap::AxisType::LeftX: rc_axis = AxisMap::AxisType::RightX; break; + case AxisMap::AxisType::LeftY: rc_axis = AxisMap::AxisType::LeftX; break; + case AxisMap::AxisType::LeftZ: rc_axis = AxisMap::AxisType::RightY; break; + case AxisMap::AxisType::RightX: rc_axis = AxisMap::AxisType::LeftY; break; + case AxisMap::AxisType::RightY: rc_axis = AxisMap::AxisType::LeftZ; break; + case AxisMap::AxisType::RightZ: rc_axis = AxisMap::AxisType::RightZ; break; + default: + throw std::invalid_argument("Unsupported axis_type in getMappedValue"); + } + } + else if (device_pid_vid == "VID_0401&PID_0401") { //Flysky FS-SM100 RC USB adapter + switch (axis_type) { + case AxisMap::AxisType::LeftX: rc_axis = AxisMap::AxisType::RightY; break; + case AxisMap::AxisType::LeftY: rc_axis = AxisMap::AxisType::LeftX; break; + case AxisMap::AxisType::LeftZ: rc_axis = AxisMap::AxisType::RightX; break; + case AxisMap::AxisType::RightX: rc_axis = AxisMap::AxisType::LeftY; break; + case AxisMap::AxisType::RightY: rc_axis = AxisMap::AxisType::LeftZ; break; + case AxisMap::AxisType::RightZ: rc_axis = AxisMap::AxisType::RightZ; break; + default: + throw std::invalid_argument("Unsupported axis_type in getMappedValue"); + } + } + else { //Xbox controllers + rc_axis = axis_type; + } + } + else + rc_axis = map.rc_axis; + + long result; + switch (rc_axis) + { + case AxisMap::AxisType::LeftX: result = di_state.x; break; + case AxisMap::AxisType::LeftY: result = di_state.y; break; + case AxisMap::AxisType::LeftZ: result = di_state.z; break; + case AxisMap::AxisType::RightX: result = di_state.rx; break; + case AxisMap::AxisType::RightY: result = di_state.ry; break; + case AxisMap::AxisType::RightZ: result = di_state.rz; break; + default: + throw std::invalid_argument("Unsupported rc_axis in getMappedValue"); + } + + return static_cast(result); + } + + float getAxisValue(AxisMap::AxisType axis_type, const AxisMap& map, const DirectInputJoyStick::JoystickState& di_state, const std::string& device_pid_vid) + { + float val = getMappedValue(axis_type, map, di_state, device_pid_vid); + + //normalize min to max --> 0 to 1 + val = (val - map.min_val) / (map.max_val - map.min_val); + + switch (map.direction) + { + case AxisMap::AxisDirection::Auto: + if ( + ((device_pid_vid == "" || device_pid_vid == "VID_0483&PID_5710") && + (axis_type == AxisMap::AxisType::LeftZ || axis_type == AxisMap::AxisType::RightY)) || + ((device_pid_vid != "" && device_pid_vid != "VID_0483&PID_5710" && device_pid_vid != "VID_0401&PID_0401") && + (axis_type == AxisMap::AxisType::LeftY)) + ) + val = 1 - val; + break; + case AxisMap::AxisDirection::Normal: break; + case AxisMap::AxisDirection::Reverse: val = 1 - val; break; + default: + throw std::invalid_argument("Unsupported map.direction in getAxisValue"); + } + + //normalize 0 to 1 --> -1 to 1 + val = 2*val - 1; + + return val; + } + +private: + static constexpr unsigned int kMaxControllers = 4; + std::unique_ptr controllers_[kMaxControllers]; +}; + +#else + +#include +#include +#include +#include +#include +#include +//#include +#include "unistd.h" + +//implementation for unsupported OS +struct SimJoyStick::impl { +private: + + + + class JoystickEvent + { + public: + /** Minimum value of axes range */ + static const short MIN_AXES_VALUE = -32768; + + /** Maximum value of axes range */ + static const short MAX_AXES_VALUE = 32767; + + /** + * The timestamp of the event, in milliseconds. + */ + unsigned int time; + + /** + * The value associated with this joystick event. + * For buttons this will be either 1 (down) or 0 (up). + * For axes, this will range between MIN_AXES_VALUE and MAX_AXES_VALUE. + */ + short value; + + /** + * The event type. + */ + unsigned char type; + + /** + * The axis/button number. + */ + unsigned char number; + + /** + * Returns true if this event is the result of a button press. + */ + bool isButton() + { + static constexpr unsigned char JS_EVENT_BUTTON = 0x01; // button pressed/released + return (type & JS_EVENT_BUTTON) != 0; + } + + /** + * Returns true if this event is the result of an axis movement. + */ + bool isAxis() + { + static constexpr unsigned char JS_EVENT_AXIS = 0x02; // joystick moved + return (type & JS_EVENT_AXIS) != 0; + } + + /** + * Returns true if this event is part of the initial state obtained when + * the joystick is first connected to. + */ + bool isInitialState() + { + static constexpr unsigned char JS_EVENT_INIT = 0x80; // initial state of device + return (type & JS_EVENT_INIT) != 0; + } + + /** + * The ostream inserter needs to be a friend so it can access the + * internal data structures. + */ + friend std::ostream& operator<<(std::ostream& os, const JoystickEvent& e); + }; + + +public: + ~impl() + { + if (fd_ >= 0) + close(fd_); + } + + static float normalizeAxisVal(int axis_val, bool wide, bool zero2One, bool reversed) + { + float min_val = wide ? -32768 : -16384; + float max_val = wide ? 32767 : 16383; + + float val = (axis_val - min_val) / (max_val - min_val); + if (zero2One) { + if (reversed) + val = 1 - val; + } + else { + val = 2*val - 1; + if (reversed) + val *= -1; + } + + return val; + } + + void getJoyStickState(int index, SimJoyStick::State& state, const AxisMaps& maps) + { + unused(maps); + + static constexpr bool blocking = false; + + //if this is new index + if (index != last_index_) { + //getJoystickInfo(1, manufacturerID, productID, state.message); + + //close previous one + if (fd_ >= 0) + close(fd_); + + //open new device + std::stringstream devicePath; + devicePath << "/dev/input/js" << index; + + fd_ = open(devicePath.str().c_str(), blocking ? O_RDONLY : O_RDONLY | O_NONBLOCK); + state.is_initialized = fd_ >= 0; + last_index_ = index; + } + + //if open was successful + if (fd_ >= 0) { + //read the device + int bytes = read(fd_, &event_, sizeof(event_)); + + //if we didn't had valid read + if (bytes == -1 || bytes != sizeof(event_)) { + // NOTE if this condition is not met, we're probably out of sync and this + // Joystick instance is likely unusable + //TODO: set below to false? + //state.is_valid = false; + } + else { + state.is_valid = true; + + if (event_.isButton()) { + if (event_.value == 0) + state.buttons &= ~(1 << event_.number); + else + state.buttons |= (1 << event_.number); + } + else if (event_.isAxis()) { + if (device_type > 0) { //RCs like FrSky Taranis + switch(event_.number) { + case 0: state.left_y = event_.value; break; + case 1: state.right_x = event_.value; break; + case 2: state.right_y = event_.value; break; + case 3: state.left_x = event_.value; break; + default: break; + } + } + else { //XBox + switch(event_.number) { + case 0: state.left_x = normalizeAxisVal(event_.value, true, false, false); break; + case 1: state.left_y = normalizeAxisVal(event_.value, false, true, true); break; + case 2: state.left_z = normalizeAxisVal(event_.value, true, false, false); break; + case 3: state.right_x = normalizeAxisVal(event_.value, true, false, false); break; + case 4: state.right_y = normalizeAxisVal(event_.value, true, false, false); break; + case 5: state.right_z = normalizeAxisVal(event_.value, true, false, false); break; + + default: break; + } + } + } + //else ignore + } + } + else + state.is_valid = false; + } + + + void setAutoCenter(unsigned int index, double strength) { + unused(index); + unused(strength); + //TODO: implement this for linux + } + + void setWheelRumble(unsigned int index, double strength) { + unused(index); + unused(strength); + //TODO: implement this for linux + } + + // bool getJoystickInfo(int index, std::string& manufacturerID, std::string& productID, std::string& message) + // { + // manufacturerID = productID = ""; + // // Use udev to look up the product and manufacturer IDs + // struct udev *udev = udev_new(); + // if (udev) { + // char sysname[32]; + // std::snprintf(sysname, sizeof(sysname), "js%u", index); + // struct udev_device *dev = udev_device_new_from_subsystem_sysname(udev, "input", sysname); + // dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); + // if (!dev) + // { + // message = "Unable to find parent USB device"; + // return false; + // } + + // std::stringstream ss; + // ss << std::hex << udev_device_get_sysattr_value(dev, "idVendor"); + // ss >> manufacturerID; + + // ss.clear(); + // ss.str(""); + // ss << std::hex << udev_device_get_sysattr_value(dev, "idProduct"); + // ss >> productID; + + // udev_device_unref(dev); + // } + // else + // { + // message = "Cannot create udev"; + // return false; + // } + // udev_unref(udev); + // return true; + // } + +private: + int last_index_ = -1; + int fd_ = -1; + JoystickEvent event_; + std::string manufacturerID, productID; + int device_type = 0; +}; + +#endif + +SimJoyStick::SimJoyStick() +{ + pimpl_.reset(new impl()); +} +SimJoyStick::~SimJoyStick() +{ + //required for pimpl +} + +void SimJoyStick::getJoyStickState(int index, SimJoyStick::State& state) const +{ + if (index < 0) { + state.is_initialized = false; + state.is_valid = false; + return; + } + + //TODO: anyway to workaround const_cast? + const_cast(this)->pimpl_->getJoyStickState(index, state, axis_maps); +} + +void SimJoyStick::setAutoCenter(int index, double strength) +{ + pimpl_->setAutoCenter(index, strength); +} + +void SimJoyStick::setWheelRumble(int index, double strength) +{ + pimpl_->setWheelRumble(index, strength); } \ No newline at end of file diff --git a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawn.cpp b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawn.cpp index 9b5d4dc2..b1c766bc 100644 --- a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawn.cpp +++ b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawn.cpp @@ -3,7 +3,7 @@ #include "GameFramework/Controller.h" #include "Components/TextRenderComponent.h" #include "Components/AudioComponent.h" -#include "WheeledVehicleMovementComponent4W.h" +#include "ChaosWheeledVehicleMovementComponent.h" #include "CarWheelFront.h" #include "CarWheelRear.h" diff --git a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawn.h b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawn.h index 64f7ccde..e9e3ea7f 100644 --- a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawn.h +++ b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawn.h @@ -1,7 +1,8 @@ #pragma once #include "CoreMinimal.h" -#include "WheeledVehicle.h" +#include "ChaosWheeledVehicleMovementComponent.h" +#include "WheeledVehiclePawn.h" #include "Components/SkeletalMeshComponent.h" #include "PhysicalMaterials/PhysicalMaterial.h" #include "UObject/ConstructorHelpers.h" @@ -26,7 +27,7 @@ class UInputComponent; class UAudioComponent; UCLASS(config = Game) -class ACarPawn : public AWheeledVehicle +class ACarPawn : public AWheeledVehiclePawn { GENERATED_BODY() diff --git a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawnSimApi.cpp b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawnSimApi.cpp index 45e3b5c4..0f8fbbaf 100644 --- a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawnSimApi.cpp +++ b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawnSimApi.cpp @@ -5,7 +5,6 @@ #include "Engine/World.h" #include "Kismet/KismetSystemLibrary.h" -#include "Kismet/GameplayStatics.h" #include "Camera/CameraComponent.h" #include "common/ClockFactory.hpp" @@ -14,7 +13,8 @@ #include "common/EarthUtils.hpp" #include "DrawDebugHelpers.h" -#include "PhysXVehicleManager.h" +#include "ChaosVehicleManager.h" +#include "vehicles/car/firmwares/physxcar/PhysXCarApi.hpp" using namespace msr::airlib; @@ -69,7 +69,7 @@ void CarPawnSimApi::createVehicleApi(ACarPawn* pawn, const msr::airlib::GeoPoint vehicle_api_ = std::unique_ptr(new PhysXCarApi(getVehicleSetting(), sensor_factory, *getGroundTruthKinematics(), home_geopoint)); pawn_ = pawn; - movement_ = pawn->GetVehicleMovement(); + movement_ = CastChecked(pawn->GetVehicleMovement()); } @@ -600,7 +600,7 @@ void CarPawnSimApi::updateWheelStates() { wheel_states_->time_stamp = msr::airlib::ClockFactory::get()->nowNanos(); - physx::PxVehicleWheelsDynData& mWheelsDynData = movement_->PVehicle->mWheelsDynData; + TArray> wheels = movement_->Wheels; const float unreal_rotation_angle_to_radians = (2 * M_PI) / -1800.0; const float unreal_steering_angle_to_radians = (M_PI) / 180.0; @@ -615,20 +615,20 @@ void CarPawnSimApi::updateWheelStates() rpm_smoothing_coeff = 0.9; } - wheel_states_->fl.rpm = wheel_states_->fl.rpm * (rpm_smoothing_coeff) + (1 - rpm_smoothing_coeff) * OmegaToRPM(mWheelsDynData.getWheelRotationSpeed(0)); - wheel_states_->fr.rpm = wheel_states_->fl.rpm * (rpm_smoothing_coeff) + (1 - rpm_smoothing_coeff) * OmegaToRPM(mWheelsDynData.getWheelRotationSpeed(1)); - wheel_states_->rl.rpm = wheel_states_->fl.rpm * (rpm_smoothing_coeff) + (1 - rpm_smoothing_coeff) * OmegaToRPM(mWheelsDynData.getWheelRotationSpeed(2)); - wheel_states_->rr.rpm = wheel_states_->fl.rpm * (rpm_smoothing_coeff) + (1 - rpm_smoothing_coeff) * OmegaToRPM(mWheelsDynData.getWheelRotationSpeed(3)); + wheel_states_->fl.rpm = wheel_states_->fl.rpm * (rpm_smoothing_coeff) + (1 - rpm_smoothing_coeff) * Chaos::OmegaToRPM(wheels[0]->GetRotationAngularVelocity()); + wheel_states_->fr.rpm = wheel_states_->fl.rpm * (rpm_smoothing_coeff) + (1 - rpm_smoothing_coeff) * Chaos::OmegaToRPM(wheels[1]->GetRotationAngularVelocity()); + wheel_states_->rl.rpm = wheel_states_->fl.rpm * (rpm_smoothing_coeff) + (1 - rpm_smoothing_coeff) * Chaos::OmegaToRPM(wheels[2]->GetRotationAngularVelocity()); + wheel_states_->rr.rpm = wheel_states_->fl.rpm * (rpm_smoothing_coeff) + (1 - rpm_smoothing_coeff) * Chaos::OmegaToRPM(wheels[3]->GetRotationAngularVelocity()); - wheel_states_->fl.rotation_angle = mWheelsDynData.getWheelRotationAngle(0); - wheel_states_->fr.rotation_angle = mWheelsDynData.getWheelRotationAngle(1); - wheel_states_->rl.rotation_angle = mWheelsDynData.getWheelRotationAngle(2); - wheel_states_->rr.rotation_angle = mWheelsDynData.getWheelRotationAngle(3); + wheel_states_->fl.rotation_angle = wheels[0]->GetRotationAngle(); + wheel_states_->fr.rotation_angle = wheels[1]->GetRotationAngle(); + wheel_states_->rl.rotation_angle = wheels[2]->GetRotationAngle(); + wheel_states_->rr.rotation_angle = wheels[3]->GetRotationAngle(); - wheel_states_->fl.steering_angle = movement_->Wheels[0]->GetSteerAngle() * unreal_steering_angle_to_radians; - wheel_states_->fr.steering_angle = movement_->Wheels[1]->GetSteerAngle() * unreal_steering_angle_to_radians; - wheel_states_->rl.steering_angle = movement_->Wheels[2]->GetSteerAngle() * unreal_steering_angle_to_radians; - wheel_states_->rr.steering_angle = movement_->Wheels[3]->GetSteerAngle() * unreal_steering_angle_to_radians; + wheel_states_->fl.steering_angle = wheels[0]->GetSteerAngle() * unreal_steering_angle_to_radians; + wheel_states_->fr.steering_angle = wheels[1]->GetSteerAngle() * unreal_steering_angle_to_radians; + wheel_states_->rl.steering_angle = wheels[2]->GetSteerAngle() * unreal_steering_angle_to_radians; + wheel_states_->rr.steering_angle = wheels[3]->GetSteerAngle() * unreal_steering_angle_to_radians; } const msr::airlib::Kinematics::State* CarPawnSimApi::getGroundTruthKinematics() const @@ -659,7 +659,7 @@ void CarPawnSimApi::updateMovement(const msr::airlib::CarApiBase::CarControls& c movement_->SetSteeringInput(controls.steering); movement_->SetBrakeInput(controls.brake); movement_->SetHandbrakeInput(controls.handbrake); - movement_->SetUseAutoGears(!controls.is_manual_gear); + movement_->SetUseAutomaticGears(!controls.is_manual_gear); } @@ -681,6 +681,7 @@ void CarPawnSimApi::resetPawn() vehicle_api_->setCarControls(msr::airlib::CarApiBase::CarControls()); updateMovement(msr::airlib::CarApiBase::CarControls()); + /* TODO Check if needed auto pv = movement_->PVehicle; if (pv) { pv->mWheelsDynData.setToRestState(); @@ -689,6 +690,7 @@ void CarPawnSimApi::resetPawn() if (pvd) { pvd->mDriveDynData.setToRestState(); } + */ }, true); UAirBlueprintLib::RunCommandOnGameThread([this, &phys_comps]() { diff --git a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawnSimApi.h b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawnSimApi.h index 48857800..4bd86718 100644 --- a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawnSimApi.h +++ b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarPawnSimApi.h @@ -1,7 +1,6 @@ #pragma once #include "GameFramework/Pawn.h" -#include "Particles/ParticleSystemComponent.h" #include "UnrealImageCapture.h" #include @@ -12,17 +11,15 @@ #include "SimJoyStick/SimJoyStick.h" #include "api/VehicleApiBase.hpp" #include "api/VehicleSimApiBase.hpp" -#include "common/common_utils/Signal.hpp" #include "common/common_utils/UniqueValueMap.hpp" #include "CoreMinimal.h" -#include "WheeledVehicleMovementComponent4W.h" +#include "ChaosWheeledVehicleMovementComponent.h" #include "CarPawn.h" #include "PawnEvents.h" #include "CarPawnSimApi.h" #include "vehicles/car/api/CarApiBase.hpp" -#include "vehicles/car/firmwares/physxcar/PhysXCarApi.hpp" #include "physics/Kinematics.hpp" #include "common/Common.hpp" #include "common/CommonStructs.hpp" @@ -166,7 +163,7 @@ class CarPawnSimApi : public msr::airlib::VehicleSimApiBase std::unique_ptr vehicle_api_; ACarPawn* pawn_; - UWheeledVehicleMovementComponent* movement_; + UChaosWheeledVehicleMovementComponent* movement_; msr::airlib::CarApiBase::CarControls last_controls_; const msr::airlib::Kinematics::State* pawn_kinematics_; std::vector vehicle_api_messages_; diff --git a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelFront.cpp b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelFront.cpp index 7e32264e..ebb2c74f 100644 --- a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelFront.cpp +++ b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelFront.cpp @@ -1,26 +1,24 @@ + + // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. #include "CarWheelFront.h" -#include "TireConfig.h" #include "UObject/ConstructorHelpers.h" UCarWheelFront::UCarWheelFront() { - ShapeRadius = 18.f; - ShapeWidth = 15.0f; - Mass = 20.0f; - DampingRate = 0.25f; + WheelRadius = 38.f; + WheelWidth = 17.0f; + //WheelMass = 20.0f; bAffectedByHandbrake = false; - SteerAngle = 40.f; + bAffectedBySteering = true; + MaxSteerAngle = 50.f; + AxleType = EAxleType::Front; // Setup suspension forces - SuspensionForceOffset = 0.0f; + SuspensionForceOffset = FVector(0.0f, 0.0f, 0.0f); SuspensionMaxRaise = 10.0f; SuspensionMaxDrop = 10.0f; - SuspensionNaturalFrequency = 9.0f; - SuspensionDampingRatio = 1.05f; - - // Find the tire object and set the data for it - static ConstructorHelpers::FObjectFinder TireData(TEXT("/AirSim/VehicleAdv/WheelData/Vehicle_FrontTireConfig.Vehicle_FrontTireConfig")); - TireConfig = TireData.Object; + //SuspensionNaturalFrequency = 9.0f; + SuspensionDampingRatio = 1.5f; } diff --git a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelFront.h b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelFront.h index 214cadd9..44f098d1 100644 --- a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelFront.h +++ b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelFront.h @@ -3,17 +3,14 @@ #pragma once #include "CoreMinimal.h" -#include "VehicleWheel.h" +#include "ChaosVehicleWheel.h" #include "CarWheelFront.generated.h" UCLASS() -class UCarWheelFront : public UVehicleWheel +class UCarWheelFront : public UChaosVehicleWheel { - GENERATED_BODY() + GENERATED_BODY() public: - UCarWheelFront(); + UCarWheelFront(); }; - - - diff --git a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelRear.cpp b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelRear.cpp index 33b859c9..a8e0aa1c 100644 --- a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelRear.cpp +++ b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelRear.cpp @@ -1,24 +1,20 @@ // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. #include "CarWheelRear.h" -#include "TireConfig.h" #include "UObject/ConstructorHelpers.h" UCarWheelRear::UCarWheelRear() { - ShapeRadius = 18.f; - ShapeWidth = 15.0f; + WheelRadius = 38.f; + WheelWidth = 17.0f; bAffectedByHandbrake = true; - SteerAngle = 0.f; + MaxSteerAngle = 0.f; + AxleType = EAxleType::Rear; // Setup suspension forces - SuspensionForceOffset = -0.0f; + SuspensionForceOffset = FVector(0.0f, 0.0f, 0.0f); SuspensionMaxRaise = 10.0f; SuspensionMaxDrop = 10.0f; - SuspensionNaturalFrequency = 9.0f; - SuspensionDampingRatio = 1.05f; - - // Find the tire object and set the data for it - static ConstructorHelpers::FObjectFinder TireData(TEXT("/AirSim/VehicleAdv/WheelData/Vehicle_BackTireConfig.Vehicle_BackTireConfig")); - TireConfig = TireData.Object; + //SuspensionNaturalFrequency = 9.0f; + SuspensionDampingRatio = 1.5f; } diff --git a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelRear.h b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelRear.h index ec2d667a..64b5df89 100644 --- a/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelRear.h +++ b/UE4Project/Plugins/AirSim/Source/Vehicles/Car/CarWheelRear.h @@ -3,17 +3,14 @@ #pragma once #include "CoreMinimal.h" -#include "VehicleWheel.h" +#include "ChaosVehicleWheel.h" #include "CarWheelRear.generated.h" UCLASS() -class UCarWheelRear : public UVehicleWheel +class UCarWheelRear : public UChaosVehicleWheel { - GENERATED_BODY() + GENERATED_BODY() public: - UCarWheelRear(); + UCarWheelRear(); }; - - - diff --git a/UE4Project/Plugins/AirSim/Source/custom_map_loader.cpp b/UE4Project/Plugins/AirSim/Source/custom_map_loader.cpp index d370a1af..d10d2080 100755 --- a/UE4Project/Plugins/AirSim/Source/custom_map_loader.cpp +++ b/UE4Project/Plugins/AirSim/Source/custom_map_loader.cpp @@ -1,195 +1,195 @@ -// This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as published by the Free Software Foundation - - -#include "custom_map_loader.h" - -static FString custom_map_path; - - -bool Ucustom_map_loader::FileLoadString(FString FileNameA, FString& SaveTextA) -{ - const TCHAR* file = *FileNameA; - UE_LOG(LogTemp, Warning, TEXT("Loading file %s"), *FileNameA); - return FFileHelper::LoadFileToString(SaveTextA, file); -} - -struct Actor { - FString type; - float x; - float y; - float heading; - float x_variance; - float y_variance; - float xy_variance; -}; - -TArray Ucustom_map_loader::ProcessFile(FString data, TArray & blue_cones, TArray & yellow_cones, TArray & big_orange_cones) { - // Get random seed for rotation of cones - srand((unsigned)time(NULL)); - - // Read the lines - TArray lines; - TArray values; - - FString left = "", new_left = ""; - FString right = data; - - while (right.Split("\n", &left, &right)) { - lines.Add(left); - - } - - lines.Add(right); - - // Process each line - for (FString& line : lines) { - FString value = ""; - - Actor actor; - - line.Split(",", &actor.type, &line); - line.Split(",", &value, &line); - actor.x = FCString::Atof(*value) * 100; - line.Split(",", &value, &line); - actor.y = FCString::Atof(*value) * 100; - line.Split(",", &value, &line); - actor.heading = FCString::Atof(*value); - line.Split(",", &value, &line); - actor.x_variance = FCString::Atof(*value); - line.Split(",", &value, &line); - actor.y_variance = FCString::Atof(*value); - line.Split(",", &value, &line ); - actor.xy_variance = FCString::Atof(*value); - - FTransform transform{ - FRotator{0.0f, float(rand() % 360), 0.0f}, // Rotation - FVector{actor.x, -actor.y, 5.0f}, // Translation - FVector{1.0f, 1.0f, 1.0f} // Scale - }; - - - if (actor.type == "yellow") { - yellow_cones.Add(transform); - } - - if (actor.type == "blue") { - blue_cones.Add(transform); - } - - if (actor.type == "big_orange") { - big_orange_cones.Add(transform); - } - } - - return lines; -} - -FTransform Ucustom_map_loader::GetFinishTransform(TArray big_orange_cones) { - - FVector location{0.0f, 0.0f, 0.0f}; - - for (FTransform & cone: big_orange_cones) { - location.X += cone.GetLocation().X; - location.Y += cone.GetLocation().Y; - } - - location.X /= big_orange_cones.Num(); - location.Y /= big_orange_cones.Num(); - - float angle = 0.0f; - if (big_orange_cones.Num() == 2) { - angle = (std::atan2f(big_orange_cones[0].GetLocation().Y - big_orange_cones[1].GetLocation().Y, big_orange_cones[0].GetLocation().X - big_orange_cones[1].GetLocation().X) - PI / 2) * 180 / PI; - } - else if (big_orange_cones.Num() == 4) { - // Get middle points of all sides of rectangle - - int max_index = 0; - float max_value = 0.0f; - std::vector midpoints; - - // Get first mid points from first orange cone - Coordinate coord_base{ big_orange_cones[0].GetLocation().X , big_orange_cones[0].GetLocation().Y }; - for (int j = 1; j < big_orange_cones.Num(); j++) { - Coordinate coord; - coord.x = (big_orange_cones[j].GetLocation().X + big_orange_cones[0].GetLocation().X) / 2; - coord.y = (big_orange_cones[j].GetLocation().Y + big_orange_cones[0].GetLocation().Y) / 2; - - float distance = getEuclideanDistance(coord_base, coord); - - if (distance > max_value) { - max_value = distance; - max_index = j - 1; - } - - midpoints.push_back(coord); - } - - // Remove point with biggest distance, this should be the diagonal - midpoints.erase(midpoints.begin() + max_index); - - // Explore other midpoints from furthest point (opposite side of rectangle with respect to big_orange_cones[0]) - int current_index = max_index + 1; - max_value = 0.0f; - int local_index = 0; - coord_base.x = big_orange_cones[current_index].GetLocation().X; - coord_base.y = big_orange_cones[current_index].GetLocation().Y; - for (int j = 1; j < big_orange_cones.Num(); j++) { - if (j == current_index) { - continue; - } - - Coordinate coord; - coord.x = (big_orange_cones[j].GetLocation().X + big_orange_cones[current_index].GetLocation().X) / 2; - coord.y = (big_orange_cones[j].GetLocation().Y + big_orange_cones[current_index].GetLocation().Y) / 2; - - midpoints.push_back(coord); - } - - - // get longest distance between midpoints - std::pair start_line; - max_value = 0.0f; - for (int i = 0; i < midpoints.size(); i++) { - for (int j = i + 1; j < midpoints.size(); j++) { - float distance = getEuclideanDistance(midpoints[i], midpoints[j]); - - if (distance > max_value) { - max_value = distance; - start_line = std::make_pair(midpoints[i], midpoints[j]); - } - } - } - - angle = (std::atan2f(start_line.second.y - start_line.first.y, start_line.second.x - start_line.first.x) - PI / 2) * 180 / PI; - } - else { - UE_LOG(LogTemp, Warning, TEXT("Only start finish lines with 2 or 4 big orange cones are supported. Angle of the start finish line will probably be incorrect.")); - } - - UE_LOG(LogTemp, Warning, TEXT("x1: %f, x2: %f, y1: %f, y2: %f"), big_orange_cones[0].GetLocation().X, big_orange_cones[1].GetLocation().X, big_orange_cones[0].GetLocation().Y, big_orange_cones[1].GetLocation().Y); - - UE_LOG(LogTemp, Warning, TEXT("Angle: %f"), angle); - - FTransform transform{ - FRotator{0.0f, angle, 0.0f}, - location, - FVector{1.0f, 1.0f, 1.0f} - }; - - return transform; -} - - -float Ucustom_map_loader::getEuclideanDistance(Coordinate coord1, Coordinate coord2) { - return std::sqrt((coord2.x - coord1.x) * (coord2.x - coord1.x) + (coord2.y - coord1.y) * (coord2.y - coord1.y)); -} - - -void Ucustom_map_loader::SetCustomMapPath(FString path) { - custom_map_path = path; -} - - -FString Ucustom_map_loader::GetCustomMapPath() { - return custom_map_path; -} +// This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as published by the Free Software Foundation + + +#include "custom_map_loader.h" + +static FString custom_map_path; + + +bool Ucustom_map_loader::FileLoadString(FString FileNameA, FString& SaveTextA) +{ + const TCHAR* file = *FileNameA; + UE_LOG(LogTemp, Warning, TEXT("Loading file %s"), *FileNameA); + return FFileHelper::LoadFileToString(SaveTextA, file); +} + +struct Actor { + FString type; + float x; + float y; + float heading; + float x_variance; + float y_variance; + float xy_variance; +}; + +TArray Ucustom_map_loader::ProcessFile(FString data, TArray & blue_cones, TArray & yellow_cones, TArray & big_orange_cones) { + // Get random seed for rotation of cones + srand((unsigned)time(NULL)); + + // Read the lines + TArray lines; + TArray values; + + FString left = "", new_left = ""; + FString right = data; + + while (right.Split("\n", &left, &right)) { + lines.Add(left); + + } + + lines.Add(right); + + // Process each line + for (FString& line : lines) { + FString value = ""; + + Actor actor; + + line.Split(",", &actor.type, &line); + line.Split(",", &value, &line); + actor.x = FCString::Atof(*value) * 100; + line.Split(",", &value, &line); + actor.y = FCString::Atof(*value) * 100; + line.Split(",", &value, &line); + actor.heading = FCString::Atof(*value); + line.Split(",", &value, &line); + actor.x_variance = FCString::Atof(*value); + line.Split(",", &value, &line); + actor.y_variance = FCString::Atof(*value); + line.Split(",", &value, &line ); + actor.xy_variance = FCString::Atof(*value); + + FTransform transform{ + FRotator{0.0f, float(rand() % 360), 0.0f}, // Rotation + FVector{actor.x, -actor.y, 5.0f}, // Translation + FVector{1.0f, 1.0f, 1.0f} // Scale + }; + + + if (actor.type == "yellow") { + yellow_cones.Add(transform); + } + + if (actor.type == "blue") { + blue_cones.Add(transform); + } + + if (actor.type == "big_orange") { + big_orange_cones.Add(transform); + } + } + + return lines; +} + +FTransform Ucustom_map_loader::GetFinishTransform(TArray big_orange_cones) { + + FVector location{0.0f, 0.0f, 0.0f}; + + for (FTransform & cone: big_orange_cones) { + location.X += cone.GetLocation().X; + location.Y += cone.GetLocation().Y; + } + + location.X /= big_orange_cones.Num(); + location.Y /= big_orange_cones.Num(); + + float angle = 0.0f; + if (big_orange_cones.Num() == 2) { + angle = (std::atan2f(big_orange_cones[0].GetLocation().Y - big_orange_cones[1].GetLocation().Y, big_orange_cones[0].GetLocation().X - big_orange_cones[1].GetLocation().X) - PI / 2) * 180 / PI; + } + else if (big_orange_cones.Num() == 4) { + // Get middle points of all sides of rectangle + + int max_index = 0; + float max_value = 0.0f; + std::vector midpoints; + + // Get first mid points from first orange cone + Coordinate coord_base{ big_orange_cones[0].GetLocation().X , big_orange_cones[0].GetLocation().Y }; + for (int j = 1; j < big_orange_cones.Num(); j++) { + Coordinate coord; + coord.x = (big_orange_cones[j].GetLocation().X + big_orange_cones[0].GetLocation().X) / 2; + coord.y = (big_orange_cones[j].GetLocation().Y + big_orange_cones[0].GetLocation().Y) / 2; + + float distance = getEuclideanDistance(coord_base, coord); + + if (distance > max_value) { + max_value = distance; + max_index = j - 1; + } + + midpoints.push_back(coord); + } + + // Remove point with biggest distance, this should be the diagonal + midpoints.erase(midpoints.begin() + max_index); + + // Explore other midpoints from furthest point (opposite side of rectangle with respect to big_orange_cones[0]) + int current_index = max_index + 1; + max_value = 0.0f; + int local_index = 0; + coord_base.x = big_orange_cones[current_index].GetLocation().X; + coord_base.y = big_orange_cones[current_index].GetLocation().Y; + for (int j = 1; j < big_orange_cones.Num(); j++) { + if (j == current_index) { + continue; + } + + Coordinate coord; + coord.x = (big_orange_cones[j].GetLocation().X + big_orange_cones[current_index].GetLocation().X) / 2; + coord.y = (big_orange_cones[j].GetLocation().Y + big_orange_cones[current_index].GetLocation().Y) / 2; + + midpoints.push_back(coord); + } + + + // get longest distance between midpoints + std::pair start_line; + max_value = 0.0f; + for (int i = 0; i < midpoints.size(); i++) { + for (int j = i + 1; j < midpoints.size(); j++) { + float distance = getEuclideanDistance(midpoints[i], midpoints[j]); + + if (distance > max_value) { + max_value = distance; + start_line = std::make_pair(midpoints[i], midpoints[j]); + } + } + } + + angle = (std::atan2f(start_line.second.y - start_line.first.y, start_line.second.x - start_line.first.x) - PI / 2) * 180 / PI; + } + else { + UE_LOG(LogTemp, Warning, TEXT("Only start finish lines with 2 or 4 big orange cones are supported. Angle of the start finish line will probably be incorrect.")); + } + + UE_LOG(LogTemp, Warning, TEXT("x1: %f, x2: %f, y1: %f, y2: %f"), big_orange_cones[0].GetLocation().X, big_orange_cones[1].GetLocation().X, big_orange_cones[0].GetLocation().Y, big_orange_cones[1].GetLocation().Y); + + UE_LOG(LogTemp, Warning, TEXT("Angle: %f"), angle); + + FTransform transform{ + FRotator{0.0f, angle, 0.0f}, + location, + FVector{1.0f, 1.0f, 1.0f} + }; + + return transform; +} + + +float Ucustom_map_loader::getEuclideanDistance(Coordinate coord1, Coordinate coord2) { + return std::sqrt((coord2.x - coord1.x) * (coord2.x - coord1.x) + (coord2.y - coord1.y) * (coord2.y - coord1.y)); +} + + +void Ucustom_map_loader::SetCustomMapPath(FString path) { + custom_map_path = path; +} + + +FString Ucustom_map_loader::GetCustomMapPath() { + return custom_map_path; +} diff --git a/UE4Project/Plugins/AirSim/Source/custom_map_loader.h b/UE4Project/Plugins/AirSim/Source/custom_map_loader.h index 05fae36d..03d3c141 100755 --- a/UE4Project/Plugins/AirSim/Source/custom_map_loader.h +++ b/UE4Project/Plugins/AirSim/Source/custom_map_loader.h @@ -1,51 +1,51 @@ -// This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as published by the Free Software Foundation - -#pragma once -#include -#include -#include -#include -#include -#include -#include - -#include "CoreMinimal.h" -#include "Kismet/BlueprintFunctionLibrary.h" -#include "custom_map_loader.generated.h" - -/** - * - */ - -struct Coordinate { - float x = 0.0f; - float y = 0.0f; -}; - -UCLASS() -class AIRSIM_API Ucustom_map_loader : public UBlueprintFunctionLibrary -{ - GENERATED_BODY() - - - - UFUNCTION(BlueprintCallable, Category = "custom map loader") - static bool FileLoadString(FString FileNameA, FString& SaveTextA); - - UFUNCTION(BlueprintCallable, Category = "custom map loader") - static TArray ProcessFile(FString data, TArray& blue_cones, TArray& yellow_cones, TArray & big_orange_cones); - - UFUNCTION(BlueprintCallable, Category = "custom map loader") - static FTransform GetFinishTransform(TArray big_orange_cones); - - UFUNCTION(BlueprintCallable, Category = "custom map loader") - static void SetCustomMapPath(FString path); - - UFUNCTION(BlueprintCallable, Category = "custom map loader") - static FString GetCustomMapPath(); - - - - - static float getEuclideanDistance(Coordinate coord1, Coordinate coord2); -}; +// This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as published by the Free Software Foundation + +#pragma once +#include +#include +#include +#include +#include +#include +#include + +#include "CoreMinimal.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "custom_map_loader.generated.h" + +/** + * + */ + +struct Coordinate { + float x = 0.0f; + float y = 0.0f; +}; + +UCLASS() +class AIRSIM_API Ucustom_map_loader : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() + + + + UFUNCTION(BlueprintCallable, Category = "custom map loader") + static bool FileLoadString(FString FileNameA, FString& SaveTextA); + + UFUNCTION(BlueprintCallable, Category = "custom map loader") + static TArray ProcessFile(FString data, TArray& blue_cones, TArray& yellow_cones, TArray & big_orange_cones); + + UFUNCTION(BlueprintCallable, Category = "custom map loader") + static FTransform GetFinishTransform(TArray big_orange_cones); + + UFUNCTION(BlueprintCallable, Category = "custom map loader") + static void SetCustomMapPath(FString path); + + UFUNCTION(BlueprintCallable, Category = "custom map loader") + static FString GetCustomMapPath(); + + + + + static float getEuclideanDistance(Coordinate coord1, Coordinate coord2); +};