diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Carla.Build.cs b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Carla.Build.cs index 339d2245e..a5ba6feb1 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Carla.Build.cs +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Carla.Build.cs @@ -7,6 +7,7 @@ using UnrealBuildTool; public class Carla : ModuleRules { bool UsingCarSim = false; + bool UsingChrono = false; private bool IsWindows(ReadOnlyTargetRules Target) { return (Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32); @@ -24,19 +25,23 @@ public class Carla : ModuleRules // Read config about carsim string CarlaPluginPath = Path.GetFullPath( ModuleDirectory ); string ConfigDir = Path.GetFullPath(Path.Combine(CarlaPluginPath, "../../../../Config/")); - string CarSimConfigFile = Path.Combine(ConfigDir, "CarSimConfig.ini"); - string[] text = System.IO.File.ReadAllLines(CarSimConfigFile); - Console.WriteLine("----------------------------------------------"); + string OptionalModulesFile = Path.Combine(ConfigDir, "OptionalModules.ini"); + string[] text = System.IO.File.ReadAllLines(OptionalModulesFile); foreach (string line in text) { - Console.WriteLine(line); if (line.Contains("CarSim ON")) { - Console.WriteLine("Enabling carsim-----------"); + Console.WriteLine("Enabling carsim"); UsingCarSim = true; PublicDefinitions.Add("WITH_CARSIM"); PrivateDefinitions.Add("WITH_CARSIM"); - Definitions.Add("WITH_CARSIM"); + } + if (line.Contains("Chrono ON")) + { + Console.WriteLine("Enabling chrono"); + UsingChrono = true; + PublicDefinitions.Add("WITH_CHRONO"); + PrivateDefinitions.Add("WITH_CHRONO"); } } @@ -173,14 +178,16 @@ public class Carla : ModuleRules { PublicAdditionalLibraries.Add(Path.Combine(LibCarlaInstallPath, "lib", GetLibName("carla_server"))); } - PublicAdditionalLibraries.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoEngine.so")); - PublicAdditionalLibraries.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoEngine_vehicle.so")); - PublicAdditionalLibraries.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoModels_vehicle.so")); - RuntimeDependencies.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoEngine.so")); - RuntimeDependencies.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoEngine_vehicle.so")); - RuntimeDependencies.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoModels_vehicle.so")); - bUseRTTI = true; - + if (UsingChrono) + { + PublicAdditionalLibraries.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoEngine.so")); + PublicAdditionalLibraries.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoEngine_vehicle.so")); + PublicAdditionalLibraries.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoModels_vehicle.so")); + RuntimeDependencies.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoEngine.so")); + RuntimeDependencies.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoEngine_vehicle.so")); + RuntimeDependencies.Add(Path.Combine(LibCarlaInstallPath, "lib/libChronoModels_vehicle.so")); + bUseRTTI = true; + } } // Include path. diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/ChronoMovementComponent.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/ChronoMovementComponent.cpp index 41cef8f61..ec0496982 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/ChronoMovementComponent.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/ChronoMovementComponent.cpp @@ -7,23 +7,42 @@ #include "ChronoMovementComponent.h" +#ifdef WITH_CHRONO using namespace chrono; using namespace chrono::vehicle; using namespace chrono::vehicle::hmmwv; +#endif void UChronoMovementComponent::CreateChronoMovementComponent( ACarlaWheeledVehicle* Vehicle) { + #ifdef WITH_CHRONO UChronoMovementComponent* ChronoMovementComponent = NewObject(Vehicle); ChronoMovementComponent->RegisterComponent(); Vehicle->SetCarlaMovementComponent(ChronoMovementComponent); + #else + UE_LOG(LogCarla, Warning, TEXT("Error: Chrono is not enabled") ); + #endif +} + +#ifdef WITH_CHRONO + +constexpr double CMTOM = 0.01; +ChVector<> UE4LocationToChrono(FVector& Location) +{ + return CMTOM*ChVector<>(Location.Y, Location.Z, -Location.X); +} +constexpr double MTOCM = 100; +FVector ChronoToUE4Location(ChVector<>& position) +{ + return MTOCM*FVector(-position.z(), position.x(), position.y()); } void UChronoMovementComponent::BeginPlay() { Super::BeginPlay(); - // DisableUE4VehiclePhysics(); + DisableUE4VehiclePhysics(); // // // Chrono system sys.Set_G_acc(ChVector<>(0, 0, 0)); @@ -36,7 +55,9 @@ void UChronoMovementComponent::BeginPlay() my_hmmwv = HMMWV_Full(&sys); my_hmmwv.SetContactMethod(ChMaterialSurface::NSC); my_hmmwv.SetChassisFixed(false); - my_hmmwv.SetInitPosition(ChCoordsys<>(ChVector<>(10, 10, 0), QUNIT)); + // Missing axis transformations to UE coordinate system + FVector VehicleLocation = CarlaVehicle->GetActorLocation(); + my_hmmwv.SetInitPosition(ChCoordsys<>(ChVector<>(UE4LocationToChrono(VehicleLocation)), QUNIT)); my_hmmwv.SetPowertrainType(PowertrainModelType::SHAFTS); my_hmmwv.SetDriveType(DrivelineType::FWD); my_hmmwv.SetTireType(TireModelType::PAC02); @@ -51,17 +72,16 @@ void UChronoMovementComponent::BeginPlay() patch->SetContactRestitutionCoefficient(0.01f); patch->SetContactMaterialProperties(2e7f, 0.3f); terrain->Initialize(); - carla::log_warning("ChronoBeginPlay"); } void UChronoMovementComponent::ProcessControl(FVehicleControl &Control) { - double Time = my_hmmwv.GetSystem()->GetChTime(); // this line crashes, my_hmmwv.GetSystem() returns an invalid pointer + double Time = my_hmmwv.GetSystem()->GetChTime(); - double Throttle = 0; //Control.Throttle; - double Steering = 0; //Control.Steer; - double Brake = 0; //Control.Brake + Control.bHandBrake; + double Throttle = Control.Throttle; + double Steering = Control.Steer; + double Brake = Control.Brake + Control.bHandBrake; my_hmmwv.Synchronize(Time, {Throttle, Steering, Brake}, *terrain.get()); terrain->Synchronize(Time); @@ -72,26 +92,43 @@ void UChronoMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { - double Time = my_hmmwv.GetSystem()->GetChTime(); // this line crashes, my_hmmwv.GetSystem() returns an invalid pointer - terrain->Advance(DeltaTime); - my_hmmwv.Advance(DeltaTime); - sys.DoStepDynamics(DeltaTime); - auto* vehicle = &my_hmmwv.GetVehicle(); // this line crashes, my_hmmwv.GetVehicle() also returns an invalid pointer - if(vehicle) + // Maximum delta time for the simulation to be stable + // TODO: make this a customizable value + const float MaxDeltaTime = 0.002; + if (DeltaTime > MaxDeltaTime) { - auto VehiclePos = vehicle->GetVehiclePos(); - auto VehicleRot = vehicle->GetVehicleRot(); - carla::log_warning("Time:", Time); - carla::log_warning("vehicle pos (", VehiclePos.x(), VehiclePos.y(), VehiclePos.z(), ")"); - carla::log_warning("vehicle rot (", VehicleRot.e1(), VehicleRot.e2(), VehicleRot.e3(), VehicleRot.e0(), ")"); - CarlaVehicle->SetActorLocation(FVector(VehiclePos.x(), VehiclePos.y(), VehiclePos.z())); - CarlaVehicle->SetActorRotation(FQuat(VehicleRot.e1(), VehicleRot.e2(), VehicleRot.e3(), VehicleRot.e0())); + uint64_t NumberSubSteps = FGenericPlatformMath::FloorToInt(DeltaTime/MaxDeltaTime); + carla::log_warning("Number of chrono substeps:", NumberSubSteps); + for (uint64_t i = 0; i < NumberSubSteps; ++i) + { + AdvanceChronoSimulation(MaxDeltaTime); + } + float RemainingTime = DeltaTime - NumberSubSteps*MaxDeltaTime; + AdvanceChronoSimulation(RemainingTime); } else { - carla::log_warning("vehicle not initialized"); + AdvanceChronoSimulation(DeltaTime); } + auto* vehicle = &my_hmmwv.GetVehicle(); + auto VehiclePos = vehicle->GetVehiclePos(); + auto VehicleRot = vehicle->GetVehicleRot(); + double Time = my_hmmwv.GetSystem()->GetChTime(); + carla::log_warning("Time:", Time); + carla::log_warning("vehicle pos (", VehiclePos.x(), VehiclePos.y(), VehiclePos.z(), ")"); + carla::log_warning("vehicle rot (", VehicleRot.e1(), VehicleRot.e2(), VehicleRot.e3(), VehicleRot.e0(), ")"); + CarlaVehicle->SetActorLocation(ChronoToUE4Location(VehiclePos)); + CarlaVehicle->SetActorRotation(FQuat(VehicleRot.e1(), VehicleRot.e2(), VehicleRot.e3(), VehicleRot.e0())); + carla::log_warning("ChronoTick"); } + +void UChronoMovementComponent::AdvanceChronoSimulation(float StepSize) +{ + terrain->Advance(StepSize); + my_hmmwv.Advance(StepSize); + sys.DoStepDynamics(StepSize); +} +#endif diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/ChronoMovementComponent.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/ChronoMovementComponent.h index 9a6ec5348..b6340f87c 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/ChronoMovementComponent.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/MovementComponents/ChronoMovementComponent.h @@ -10,6 +10,7 @@ #include "BaseCarlaMovementComponent.h" #include "Carla/Vehicle/VehicleControl.h" +#ifdef WITH_CHRONO #include "compiler/disable-ue4-macros.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wall" @@ -22,6 +23,7 @@ #pragma clang diagnostic pop #include "compiler/enable-ue4-macros.h" +#endif #include "ChronoMovementComponent.generated.h" @@ -30,15 +32,18 @@ class CARLA_API UChronoMovementComponent : public UBaseCarlaMovementComponent { GENERATED_BODY() +#ifdef WITH_CHRONO chrono::ChSystemNSC sys; chrono::vehicle::hmmwv::HMMWV_Full my_hmmwv; std::shared_ptr terrain; +#endif public: static void CreateChronoMovementComponent(ACarlaWheeledVehicle* Vehicle); + #ifdef WITH_CHRONO virtual void BeginPlay() override; void ProcessControl(FVehicleControl &Control) override; @@ -47,4 +52,6 @@ public: ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + void AdvanceChronoSimulation(float StepSize); + #endif }; diff --git a/Util/BuildTools/BuildCarlaUE4.sh b/Util/BuildTools/BuildCarlaUE4.sh index 83de651ae..db8eb2797 100755 --- a/Util/BuildTools/BuildCarlaUE4.sh +++ b/Util/BuildTools/BuildCarlaUE4.sh @@ -13,11 +13,12 @@ HARD_CLEAN=false BUILD_CARLAUE4=false LAUNCH_UE4_EDITOR=false USE_CARSIM=false +USE_CHRONO=false GDB= RHI="-vulkan" -OPTS=`getopt -o h --long help,build,rebuild,launch,clean,hard-clean,gdb,opengl,carsim -n 'parse-options' -- "$@"` +OPTS=`getopt -o h --long help,build,rebuild,launch,clean,hard-clean,gdb,opengl,carsim,chrono -n 'parse-options' -- "$@"` eval set -- "$OPTS" @@ -49,6 +50,9 @@ while [[ $# -gt 0 ]]; do --carsim ) USE_CARSIM=true; shift ;; + --chrono ) + USE_CHRONO=true + shift ;; -h | --help ) echo "$DOC_STRING" echo "$USAGE_STRING" @@ -117,13 +121,20 @@ fi if ${BUILD_CARLAUE4} ; then + FILE_TEXT="" if ${USE_CARSIM} ; then python ${PWD}/../../Util/BuildTools/enable_carsim_to_uproject.py -f="CarlaUE4.uproject" -e - echo "CarSim ON" > ${PWD}/Config/CarSimConfig.ini + FILE_TEXT="CarSim ON"$'\n'"${FILE_TEXT}" else python ${PWD}/../../Util/BuildTools/enable_carsim_to_uproject.py -f="CarlaUE4.uproject" - echo "CarSim OFF" > ${PWD}/Config/CarSimConfig.ini + FILE_TEXT="CarSim OFF"$'\n'"${FILE_TEXT}" fi + if ${USE_CHRONO} ; then + FILE_TEXT="Chrono ON"$'\n'"${FILE_TEXT}" + else + FILE_TEXT="Chrono OFF"$'\n'"${FILE_TEXT}" + fi + echo ${FILE_TEXT} > ${PWD}/Config/OptionalModules.ini if [ ! -f Makefile ]; then diff --git a/Util/BuildTools/Setup.sh b/Util/BuildTools/Setup.sh index b8b6369c2..7c3fe34e1 100755 --- a/Util/BuildTools/Setup.sh +++ b/Util/BuildTools/Setup.sh @@ -8,17 +8,21 @@ DOC_STRING="Download and install the required libraries for carla." USAGE_STRING="Usage: $0 [--python-version=VERSION]" -OPTS=`getopt -o h --long help,python-version: -n 'parse-options' -- "$@"` +OPTS=`getopt -o h --long help,chrono,python-version: -n 'parse-options' -- "$@"` eval set -- "$OPTS" PY_VERSION_LIST=3 +USE_CHRONO=false while [[ $# -gt 0 ]]; do case "$1" in --python-version ) PY_VERSION_LIST="$2"; shift 2 ;; + --chrono ) + USE_CHRONO=true; + shift ;; -h | --help ) echo "$DOC_STRING" echo "$USAGE_STRING" @@ -461,6 +465,82 @@ else rm -Rf ${XERCESC_SRC_DIR} fi +if ${USE_CHRONO} ; then + + # ============================================================================== + # -- Get Eigen headers (Chrono dependency) ------------------------------------- + # ============================================================================== + + EIGEN_VERSION=3.3.7 + EIGEN_REPO=https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.tar.gz + EIGEN_BASENAME=eigen-${EIGEN_VERSION} + + EIGEN_SRC_DIR=eigen-${EIGEN_VERSION}-src + EIGEN_INSTALL_DIR=eigen-${EIGEN_VERSION}-install + EIGEN_INCLUDE=${EIGEN_INSTALL_DIR}/include + + + if [[ -d ${EIGEN_INSTALL_DIR} ]] ; then + log "Eigen already installed." + else + log "Retrieving Eigen." + wget ${EIGEN_REPO} + + log "Extracting Eigen." + tar -xzf ${EIGEN_BASENAME}.tar.gz + mv ${EIGEN_BASENAME} ${EIGEN_SRC_DIR} + mkdir -p ${EIGEN_INCLUDE}/unsupported + mv ${EIGEN_SRC_DIR}/Eigen ${EIGEN_INCLUDE} + mv ${EIGEN_SRC_DIR}/unsupported/Eigen ${EIGEN_INCLUDE}/unsupported/Eigen + + rm -Rf ${EIGEN_BASENAME}.tar.gz + rm -Rf ${EIGEN_SRC_DIR} + fi + + mkdir -p ${LIBCARLA_INSTALL_SERVER_FOLDER}/include/ + cp -p -r ${EIGEN_INCLUDE}/* ${LIBCARLA_INSTALL_SERVER_FOLDER}/include/ + + # ============================================================================== + # -- Get Chrono and compile it with libc++ ------------------------------------- + # ============================================================================== + + CHRONO_TAG=5.0.1 + CHRONO_REPO=https://github.com/projectchrono/chrono.git + + CHRONO_SRC_DIR=chrono-source + CHRONO_INSTALL_DIR=chrono-install + + if [[ -d ${CHRONO_INSTALL_DIR} ]] ; then + log "chrono library already installed." + else + log "Retrieving chrono library." + git clone --depth 1 --branch ${CHRONO_TAG} ${CHRONO_REPO} ${CHRONO_SRC_DIR} + + mkdir -p ${CHRONO_SRC_DIR}/build + + pushd ${CHRONO_SRC_DIR}/build >/dev/null + + cmake -G "Ninja" \ + -DCMAKE_CXX_FLAGS="-fPIC -std=c++14 -stdlib=libc++ -I${LLVM_INCLUDE} -L${LLVM_LIBPATH} -Wno-unused-command-line-argument" \ + -DEIGEN3_INCLUDE_DIR="../../${EIGEN_INCLUDE}" \ + -DCMAKE_INSTALL_PREFIX="../../${CHRONO_INSTALL_DIR}" \ + -DENABLE_MODULE_VEHICLE=ON \ + .. + ninja + ninja install + + popd >/dev/null + + rm -Rf ${CHRONO_SRC_DIR} + fi + + mkdir -p ${LIBCARLA_INSTALL_SERVER_FOLDER}/lib/ + mkdir -p ${LIBCARLA_INSTALL_SERVER_FOLDER}/include/ + cp -p ${CHRONO_INSTALL_DIR}/lib/*.so ${LIBCARLA_INSTALL_SERVER_FOLDER}/lib/ + cp -p -r ${CHRONO_INSTALL_DIR}/include/* ${LIBCARLA_INSTALL_SERVER_FOLDER}/include/ + +fi + # ============================================================================== # -- Generate Version.h -------------------------------------------------------- # ============================================================================== @@ -511,7 +591,7 @@ cat >>${LIBCPP_TOOLCHAIN_FILE}.gen <