diff --git a/CMake/Options/Common.cmake b/CMake/Options/Common.cmake index 83720960b..694b0992b 100644 --- a/CMake/Options/Common.cmake +++ b/CMake/Options/Common.cmake @@ -91,3 +91,15 @@ option ( "Whether to convert build warnings to errors." OFF ) + +carla_string_option ( + GCC_COMPILER + "gcc compiler used by some CARLA extensions." + /usr/bin/gcc-7 +) + +carla_string_option ( + GXX_COMPILER + "g++ compiler used by some CARLA extensions." + /usr/bin/g++-7 +) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2355405ab..ac3e2dfea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,6 +151,11 @@ if (BUILD_OSM_WORLD_RENDERER) add_subdirectory (osm-world-renderer) endif () +if (ENABLE_ROS2) + set (BOOST_INCLUDE_PATH ${CMAKE_BINARY_DIR}/_deps/boost-src/libs) + add_subdirectory (Ros2Native) +endif() + if (BUILD_PYTHON_API) add_subdirectory (PythonAPI) endif () diff --git a/LibCarla/CMakeLists.txt b/LibCarla/CMakeLists.txt index 67d7c6235..2faf626a7 100644 --- a/LibCarla/CMakeLists.txt +++ b/LibCarla/CMakeLists.txt @@ -103,6 +103,7 @@ if (BUILD_CARLA_SERVER) LIBCARLA_SERVER_HEADERS ${LIBCARLA_SERVER_HEADERS_ROS2} ) + set (CARLA_ROS2_DEFINITIONS WITH_ROS2) endif () file ( @@ -146,8 +147,13 @@ if (BUILD_CARLA_SERVER) ${CARLA_COMMON_DEFINITIONS} ${CARLA_EXCEPTION_DEFINITIONS} ${CARLA_RTTI_DEFINITIONS} + ${CARLA_ROS2_DEFINITIONS} ) - + + if (ENABLE_ROS2) + add_dependencies (carla-server carla-ros2-native) + endif () + endif () @@ -192,19 +198,6 @@ if (BUILD_CARLA_CLIENT) ${LIBCARLA_SOURCE_PATH}/carla/trafficmanager/*.h ${LIBCARLA_SOURCE_PATH}/compiler/*.h ) - - if (ENABLE_ROS2) - file ( - GLOB - LIBCARLA_CLIENT_HEADERS_ROS2 - ${LIBCARLA_SOURCE_PATH}/carla/ros2/*.h - ) - list ( - APPEND - LIBCARLA_CLIENT_HEADERS - ${LIBCARLA_CLIENT_HEADERS_ROS2} - ) - endif () if (ENABLE_RSS) file ( @@ -256,19 +249,6 @@ if (BUILD_CARLA_CLIENT) ${LIBCARLA_SOURCE_PATH}/carla/multigpu/*.cpp ${LIBCARLA_SOURCE_PATH}/carla/trafficmanager/*.cpp ) - - if (ENABLE_ROS2) - file ( - GLOB - LIBCARLA_CLIENT_SOURCES_ROS2 - ${LIBCARLA_SOURCE_PATH}/carla/ros2/*.cpp - ) - list ( - APPEND - LIBCARLA_CLIENT_SOURCES - ${LIBCARLA_CLIENT_SOURCES_ROS2} - ) - endif () if (ENABLE_RSS) file ( diff --git a/LibCarla/source/carla/ros2/ROS2CallbackData.h b/LibCarla/source/carla/ros2/ROS2CallbackData.h index 46f331edd..a470e16be 100644 --- a/LibCarla/source/carla/ros2/ROS2CallbackData.h +++ b/LibCarla/source/carla/ros2/ROS2CallbackData.h @@ -6,6 +6,16 @@ #pragma once +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4583) +#pragma warning(disable:4582) +#include +#pragma warning(pop) +#else +#include +#endif + #include #include @@ -23,7 +33,7 @@ namespace ros2 { bool manual_gear_shift; }; - using ROS2CallbackData = std::variant; + using ROS2CallbackData = boost::variant2::variant; using ActorCallback = std::function; diff --git a/Ros2Native/CMakeLists.txt b/Ros2Native/CMakeLists.txt new file mode 100644 index 000000000..52851d2ba --- /dev/null +++ b/Ros2Native/CMakeLists.txt @@ -0,0 +1,53 @@ +cmake_minimum_required (VERSION 3.28.0) + +project(carla-ros2-native-project) + +include (${CARLA_WORKSPACE_PATH}/CMake/CarlaOptions.cmake) +include (ExternalProject) + +set (PROJECT_INSTALL_PATH ${CMAKE_CURRENT_BINARY_DIR}/install) +set (PROJECT_CMAKE_FLAGS -DCMAKE_CXX_COMPILER=${GXX_COMPILER} -DCMAKE_C_COMPILER=${GCC_COMPILER} -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS_RELEASE=-D_GLIBCXX_USE_CXX11_ABI=0 -DCMAKE_INSTALL_PREFIX=${PROJECT_INSTALL_PATH}) + +ExternalProject_add ( + foonathan_memory + URL https://github.com/eProsima/foonathan_memory_vendor/archive/refs/heads/master.zip + CMAKE_ARGS ${PROJECT_CMAKE_FLAGS} -DBUILD_SHARED_LIBS=ON -DFOONATHAN_MEMORY_FORCE_VENDORED_BUILD=ON +) + +ExternalProject_add ( + fastcdr + URL https://github.com/eProsima/Fast-CDR/archive/refs/heads/1.1.x.zip + CMAKE_ARGS ${PROJECT_CMAKE_FLAGS} +) + +# Note: We are using GIT_REPOSITORY instead URL for fastdds because fastdss contains submodules +# and we need the .git folders to download the submodules +ExternalProject_add ( + fastdds + GIT_REPOSITORY https://github.com/eProsima/Fast-DDS.git + GIT_TAG 2.11.2 + CMAKE_ARGS ${PROJECT_CMAKE_FLAGS} -DTHIRDPARTY_Asio=FORCE -DTHIRDPARTY_TinyXML2=FORCE + DEPENDS foonathan_memory fastcdr +) + +ExternalProject_Add( + carla-ros2-native-lib + DEPENDS fastdds + SOURCE_DIR ${PROJECT_SOURCE_DIR}/LibCarlaRos2Native + CMAKE_ARGS ${PROJECT_CMAKE_FLAGS} -DBOOST_INCLUDE_PATH=${BOOST_INCLUDE_PATH} +) + +set (CARLA_PLUGIN_BINARY_PATH ${CMAKE_SOURCE_DIR}/Unreal/CarlaUnreal/Plugins/Carla/Binaries/Linux) +add_custom_command( + TARGET carla-ros2-native-lib + POST_BUILD + COMMAND cmake -E make_directory ${CARLA_PLUGIN_BINARY_PATH} + COMMAND ${CMAKE_COMMAND} -E copy + ${PROJECT_INSTALL_PATH}/lib/*.so* + ${CARLA_PLUGIN_BINARY_PATH} +) + +add_custom_target ( + carla-ros2-native + DEPENDS carla-ros2-native-lib +) \ No newline at end of file diff --git a/Ros2Native/LibCarlaRos2Native/CMakeLists.txt b/Ros2Native/LibCarlaRos2Native/CMakeLists.txt new file mode 100644 index 000000000..3f9ce83c9 --- /dev/null +++ b/Ros2Native/LibCarlaRos2Native/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required (VERSION 3.28.0) + +project(carla-ros2-native) + +set (LIBCARLA_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../LibCarla/source) + +file ( + GLOB + LIBCARLA_ROS2_SOURCES + ${LIBCARLA_SOURCE_PATH}/carla/ros2/publishers/*.cpp + ${LIBCARLA_SOURCE_PATH}/carla/ros2/subscribers/*.cpp + ${LIBCARLA_SOURCE_PATH}/carla/ros2/listeners/*.cpp + ${LIBCARLA_SOURCE_PATH}/carla/ros2/types/*.cpp +) + +file ( + GLOB + LIBCARLA_ROS2_HEADERS + ${LIBCARLA_SOURCE_PATH}/carla/ros2/publishers/*.h + ${LIBCARLA_SOURCE_PATH}/carla/ros2/subscribers/*.h + ${LIBCARLA_SOURCE_PATH}/carla/ros2/listeners/*.h + ${LIBCARLA_SOURCE_PATH}/carla/ros2/types/*.h +) + +add_library (carla-ros2-native SHARED + ${LIBCARLA_ROS2_HEADERS} + ${LIBCARLA_ROS2_SOURCES} +) + +target_include_directories (carla-ros2-native SYSTEM PRIVATE + ${LIBCARLA_SOURCE_PATH} + ${CMAKE_INSTALL_PREFIX}/include + ${BOOST_INCLUDE_PATH}/variant2/include + ${BOOST_INCLUDE_PATH}/mp11/include + ${BOOST_INCLUDE_PATH}/assert/include + ${BOOST_INCLUDE_PATH}/config/include +) + +target_compile_definitions (carla-ros2-native PUBLIC + BOOST_ASIO_ENABLE_BUFFER_DEBUGGING +) + +target_link_libraries(carla-ros2-native + ${CMAKE_INSTALL_PREFIX}/lib/libfastrtps.so) + +install (TARGETS carla-ros2-native DESTINATION lib) \ No newline at end of file diff --git a/Unreal/CMakeLists.txt b/Unreal/CMakeLists.txt index 28f18b080..7308f9869 100644 --- a/Unreal/CMakeLists.txt +++ b/Unreal/CMakeLists.txt @@ -23,6 +23,10 @@ set ( ${CARLA_UE_PATH}/CarlaUnreal.uproject ) +if (ENABLE_ROS2) + set (LAUNCH_ARGS ${LAUNCH_ARGS} --ros2) +endif() + if (WIN32) set ( CARLA_UE_GENERATE_PROJECT_FILES_COMMAND diff --git a/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Actor/ActorDispatcher.cpp b/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Actor/ActorDispatcher.cpp index 1486fff9e..a1950e908 100644 --- a/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Actor/ActorDispatcher.cpp +++ b/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Actor/ActorDispatcher.cpp @@ -213,7 +213,7 @@ FCarlaActor* UActorDispatcher::RegisterActor( { AActor *UEActor = reinterpret_cast(Actor); ActorROS2Handler Handler(UEActor, RosName); - std::visit(Handler, Data); + boost::variant2::visit(Handler, Data); }); } } diff --git a/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Carla.Build.cs.in b/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Carla.Build.cs.in index a904b0647..3fbbcf0b3 100644 --- a/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Carla.Build.cs.in +++ b/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Carla.Build.cs.in @@ -1,7 +1,9 @@ // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. using System; +using System.IO; using UnrealBuildTool; +using System.Diagnostics; using EpicGames.Core; public class Carla : @@ -20,7 +22,7 @@ public class Carla : bool EnablePytorch = false; [CommandLine("-ros2")] - bool EnableRos2 = false; + bool EnableRos2 = "${ENABLE_ROS2}".Equals("ON"); [CommandLine("-osm2odr")] bool EnableOSM2ODR = false; @@ -30,6 +32,14 @@ public class Carla : public Carla(ReadOnlyTargetRules Target) : base(Target) { + void AddDynamicLibrary(string library) + { + PublicAdditionalLibraries.Add(library); + RuntimeDependencies.Add(library); + PublicDelayLoadDLLs.Add(library); + Console.WriteLine("Dynamic Library Added: " + library); + } + bool IsWindows = Target.Platform == UnrealTargetPlatform.Win64; PrivatePCHHeaderFile = "Carla.h"; @@ -55,7 +65,6 @@ public class Carla : TestOptionalFeature(EnableCarSim, "CarSim support", "WITH_CARSIM"); TestOptionalFeature(EnableChrono, "Chrono support", "WITH_CHRONO"); TestOptionalFeature(EnablePytorch, "PyTorch support", "WITH_PYTORCH"); - TestOptionalFeature(EnableRos2, "ROS2 support", "WITH_ROS2"); TestOptionalFeature(EnableOSM2ODR, "OSM2ODR support", "WITH_OSM2ODR"); PrivateDependencyModuleNames.AddRange(new string[] @@ -141,6 +150,19 @@ public class Carla : }; } + if (EnableRos2) + { + PrivateDefinitions.Add("WITH_ROS2"); + PrivateDefinitions.Add("WITH_ROS2"); + + string CarlaPluginSourcePath = Path.GetFullPath(ModuleDirectory); + string CarlaPluginBinariesLinuxPath = Path.Combine(CarlaPluginSourcePath, "..", "..", "Binaries", "Linux"); + AddDynamicLibrary(Path.Combine(CarlaPluginBinariesLinuxPath, "libcarla-ros2-native.so")); + AddDynamicLibrary(Path.Combine(CarlaPluginBinariesLinuxPath, "libfoonathan_memory-0.7.3.so")); + AddDynamicLibrary(Path.Combine(CarlaPluginBinariesLinuxPath, "libfastcdr.so")); + AddDynamicLibrary(Path.Combine(CarlaPluginBinariesLinuxPath, "libfastrtps.so")); + } + PublicDefinitions.AddRange(new string[] { "ASIO_NO_EXCEPTIONS", diff --git a/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Game/CarlaEngine.cpp b/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Game/CarlaEngine.cpp index 744757c19..cc662ed83 100644 --- a/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Game/CarlaEngine.cpp +++ b/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Game/CarlaEngine.cpp @@ -220,9 +220,16 @@ void FCarlaEngine::NotifyInitGame(const UCarlaSettings &Settings) #if defined(WITH_ROS2) if (Settings.ROS2) { + UE_LOG(LogCarla, Log, TEXT("ROS2: Creating ROS2 Instance...")); auto ROS2 = carla::ros2::ROS2::GetInstance(); + UE_LOG(LogCarla, Log, TEXT("ROS2: Enabling ROS2...")); ROS2->Enable(true); + UE_LOG(LogCarla, Log, TEXT("ROS2: ROS2 enabled...")); + } else { + UE_LOG(LogCarla, Log, TEXT("ROS2: ROS2 enabled...")); } + #else + UE_LOG(LogCarla, Log, TEXT("ROS2: ROS2 extension not build...")); #endif bMapChanged = true; diff --git a/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Sensor/Sensor.h b/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Sensor/Sensor.h index ea9741761..724014f65 100644 --- a/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Sensor/Sensor.h +++ b/Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Sensor/Sensor.h @@ -148,7 +148,7 @@ protected: { TRACE_CPUPROFILER_EVENT_SCOPE_STR("ROS2 Send PixelReader"); auto StreamId = carla::streaming::detail::token_type(Sensor.GetToken()).get_stream_id(); - auto Res = std::async(std::launch::async, [&Sensor, ROS2, &Stream, StreamId, BufView]() + auto Res = std::async(std::launch::async, [&Sensor, ROS2, &Stream, StreamId, BufferView]() { // get resolution of camera int W = -1, H = -1; @@ -167,11 +167,11 @@ protected: if (ParentActor) { FTransform LocalTransformRelativeToParent = Sensor.GetActorTransform().GetRelativeTransform(ParentActor->GetActorTransform()); - ROS2->ProcessDataFromCamera(Stream.GetSensorType(), StreamId, LocalTransformRelativeToParent, W, H, Fov, BufView, &Sensor); + ROS2->ProcessDataFromCamera(Stream.GetSensorType(), StreamId, LocalTransformRelativeToParent, W, H, Fov, BufferView, &Sensor); } else { - ROS2->ProcessDataFromCamera(Stream.GetSensorType(), StreamId, Stream.GetSensorTransform(), W, H, Fov, BufView, &Sensor); + ROS2->ProcessDataFromCamera(Stream.GetSensorType(), StreamId, Stream.GetSensorTransform(), W, H, Fov, BufferView, &Sensor); } }); }