cmake_minimum_required(VERSION 3.0.2) project(mission_adapters VERSION 0.2.0 LANGUAGES CXX) # ======================================================== # Build mode detection # ======================================================== if(DEFINED CATKIN_DEVEL_PREFIX OR DEFINED CATKIN_TOPLEVEL) set(BUILDING_WITH_CATKIN TRUE) message(STATUS "Building mission_adapters with Catkin") else() set(BUILDING_WITH_CATKIN FALSE) message(STATUS "Building mission_adapters with Standalone CMake") endif() # ======================================================== # C++ Standard # ======================================================== set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # ======================================================== # Common dependencies # # Chỉ những thứ code thật sự dùng: message contract (robot_protocol_msgs / robot_geometry_msgs), # tiện ích ROS-like (robot_cpp / robot_time) và Boost header (boost::shared_ptr trong message). # PCL / OpenMP / Eigen của bản trước là di sản copy từ template planner, gói này không dùng. # ======================================================== # Boost.DLL cần system + filesystem để nạp plugin theo library_path. find_package(Boost REQUIRED COMPONENTS system filesystem) find_package(Threads REQUIRED) find_package(yaml-cpp REQUIRED) # ======================================================== # Standalone configuration # ======================================================== if(NOT BUILDING_WITH_CATKIN) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) set(CMAKE_BUILD_RPATH "${CMAKE_BINARY_DIR}") # Test/ -> src/AMR_T800/pnkx_nav_core/src set(PNKX_NAV_CORE_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../pnkx_nav_core/src" ) # Test/ -> T800_ws/devel/lib set(WORKSPACE_DEVEL_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../devel/lib" ) file(GLOB STANDALONE_PACKAGE_INCLUDE_DIRS LIST_DIRECTORIES true ${PNKX_NAV_CORE_SRC_DIR}/*/include ${PNKX_NAV_CORE_SRC_DIR}/*/*/include ${PNKX_NAV_CORE_SRC_DIR}/*/*/*/include ${PNKX_NAV_CORE_SRC_DIR}/*/*/*/*/include ) set(STANDALONE_INCLUDE_DIRS ${STANDALONE_PACKAGE_INCLUDE_DIRS} /usr/local/include ) set(PACKAGES_DIR robot_cpp robot_time robot_xmlrpcpp ) if(EXISTS ${WORKSPACE_DEVEL_LIB_DIR}) link_directories(${WORKSPACE_DEVEL_LIB_DIR}) endif() link_directories(/usr/local/lib) # ======================================================== # Catkin configuration # ======================================================== else() find_package(catkin REQUIRED COMPONENTS robot_cpp robot_time robot_geometry_msgs robot_protocol_msgs robot_std_msgs ) catkin_package( INCLUDE_DIRS include LIBRARIES mission_adapters CATKIN_DEPENDS robot_cpp robot_time robot_geometry_msgs robot_protocol_msgs robot_std_msgs DEPENDS Boost ) include_directories(include) # SYSTEM: header của dependency (robot_cpp/console.h khai hàng chục hằng màu không dùng) sẽ ngập # warning dưới -Wall -Wextra và che mất warning của chính gói này. include_directories(SYSTEM ${catkin_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ) endif() # ======================================================== # Core library # ======================================================== add_library(mission_adapters SHARED src/types.cpp src/event.cpp src/mission_manager.cpp src/mission_executor.cpp src/event_processor.cpp src/mission_config.cpp src/plugin_registry.cpp ) # Gói này KHÔNG kế thừa cờ -w của pnkx_nav_core: warning ở đây phải nhìn thấy được. target_compile_options(mission_adapters PRIVATE -Wall -Wextra) target_include_directories(mission_adapters PUBLIC $ $ ) # ======================================================== # Linking # ======================================================== if(BUILDING_WITH_CATKIN) add_dependencies(mission_adapters ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS} ) target_link_libraries(mission_adapters PUBLIC ${catkin_LIBRARIES} PRIVATE Boost::boost Boost::system Boost::filesystem Threads::Threads ${CMAKE_DL_LIBS} yaml-cpp ) else() target_include_directories(mission_adapters PRIVATE ${STANDALONE_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ) target_link_libraries(mission_adapters PUBLIC ${PACKAGES_DIR} PRIVATE Boost::boost Boost::system Boost::filesystem Threads::Threads ${CMAKE_DL_LIBS} yaml-cpp ) set_target_properties(mission_adapters PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} BUILD_RPATH "${CMAKE_BINARY_DIR}" INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib" ) endif() # ======================================================== # Plugins — mỗi nguồn mission là một .so riêng. # # Tên file .so phải khớp khoá `library_path` trong # `pnkx_nav_core/config/mission_adapters_params.yaml`; tên symbol export phải khớp khoá `type` # trong `mission_sources`. Lệch một trong hai thì build vẫn sạch còn runtime báo "không tìm thấy". # ======================================================== set(MISSION_ADAPTERS_PLUGIN_TARGETS mission_adapters_goal_source mission_adapters_vda5050_source ) add_library(mission_adapters_goal_source SHARED plugins/goal_source_adapter.cpp) add_library(mission_adapters_vda5050_source SHARED plugins/vda5050_source_adapter.cpp) foreach(plugin_target ${MISSION_ADAPTERS_PLUGIN_TARGETS}) target_compile_options(${plugin_target} PRIVATE -Wall -Wextra) set_target_properties(${plugin_target} PROPERTIES POSITION_INDEPENDENT_CODE ON) target_include_directories(${plugin_target} PUBLIC $ ) target_link_libraries(${plugin_target} PUBLIC mission_adapters PRIVATE Boost::boost Threads::Threads ) if(NOT BUILDING_WITH_CATKIN) target_include_directories(${plugin_target} PRIVATE ${STANDALONE_INCLUDE_DIRS}) target_link_libraries(${plugin_target} PRIVATE ${PACKAGES_DIR}) set_target_properties(${plugin_target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} BUILD_RPATH "${CMAKE_BINARY_DIR}" INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib" ) endif() endforeach() # ======================================================== # Example # # Có build để tài liệu không trôi khỏi API: đổi contract mà quên ví dụ thì build gãy ngay. # ======================================================== option(BUILD_MISSION_ADAPTERS_EXAMPLES "Build mission_adapters examples" ON) if(BUILD_MISSION_ADAPTERS_EXAMPLES) add_executable(robot_control_example examples/robot_control_example.cpp) target_compile_options(robot_control_example PRIVATE -Wall -Wextra) target_link_libraries(robot_control_example PRIVATE mission_adapters Threads::Threads ) if(NOT BUILDING_WITH_CATKIN) target_include_directories(robot_control_example PRIVATE ${STANDALONE_INCLUDE_DIRS} ) target_link_libraries(robot_control_example PRIVATE ${PACKAGES_DIR}) endif() # Demo: chạy một VDA5050 Order qua VDA5050SourceAdapter và in ra các chặng thu được. # Link thẳng plugin source adapter thay vì nạp qua boost::dll — demo chỉ cần xem kết quả cắt # chặng, không cần kiểm tra đường nạp plugin. add_executable(vda5050_order_demo examples/vda5050_order_demo.cpp) target_compile_options(vda5050_order_demo PRIVATE -Wall -Wextra) target_link_libraries(vda5050_order_demo PRIVATE mission_adapters mission_adapters_vda5050_source Threads::Threads ) if(NOT BUILDING_WITH_CATKIN) target_include_directories(vda5050_order_demo PRIVATE ${STANDALONE_INCLUDE_DIRS}) target_link_libraries(vda5050_order_demo PRIVATE ${PACKAGES_DIR}) endif() endif() # ======================================================== # Install # ======================================================== if(BUILDING_WITH_CATKIN) install(TARGETS mission_adapters ${MISSION_ADAPTERS_PLUGIN_TARGETS} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} ) install(DIRECTORY include/${PROJECT_NAME}/ DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} FILES_MATCHING PATTERN "*.h" ) else() install(TARGETS mission_adapters ${MISSION_ADAPTERS_PLUGIN_TARGETS} EXPORT ${PROJECT_NAME}-targets ARCHIVE DESTINATION lib LIBRARY DESTINATION lib RUNTIME DESTINATION bin ) install(EXPORT ${PROJECT_NAME}-targets FILE ${PROJECT_NAME}-targets.cmake NAMESPACE ${PROJECT_NAME}:: DESTINATION lib/cmake/${PROJECT_NAME} ) install(DIRECTORY include/${PROJECT_NAME}/ DESTINATION include FILES_MATCHING PATTERN "*.h" ) endif() # ======================================================== # Tests # # Gói này đăng ký test với catkin/ctest (chạy được qua `catkin_make run_tests`) VÀ mở # EXCLUDE_FROM_ALL để binary có mặt sau `catkin_make` thường — chạy thẳng # ./devel/lib/mission_adapters/ theo đúng quy trình verify của repo. # ======================================================== if(CATKIN_ENABLE_TESTING AND BUILDING_WITH_CATKIN) if(NOT COMMAND catkin_add_gtest) message(FATAL_ERROR "catkin_add_gtest NOT FOUND") endif() set(MISSION_ADAPTERS_TESTS event_bus_test adapter_test mission_manager_test mission_lifecycle_test plugin_registry_test ) foreach(test_name ${MISSION_ADAPTERS_TESTS}) catkin_add_gtest(${test_name} test/${test_name}.cpp) if(TARGET ${test_name}) set_target_properties(${test_name} PROPERTIES EXCLUDE_FROM_ALL FALSE) target_compile_options(${test_name} PRIVATE -Wall -Wextra) target_include_directories(${test_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/test ) target_include_directories(${test_name} SYSTEM PRIVATE ${catkin_INCLUDE_DIRS} ) # catkin_add_gtest dùng target_link_libraries dạng plain, nên phần bổ sung cũng phải plain. # # Test link thẳng plugin .so để kiểm logic chuyển đổi ở mức unit; đường nạp qua Boost.DLL # được kiểm riêng trong plugin_registry_test. target_link_libraries(${test_name} mission_adapters ${MISSION_ADAPTERS_PLUGIN_TARGETS} ${catkin_LIBRARIES} pthread ) # plugin_registry_test nạp .so từ devel/lib theo library_path, nên cần cả hai plugin đã build. add_dependencies(${test_name} ${MISSION_ADAPTERS_PLUGIN_TARGETS}) # Đường tới cây config và thư mục .so của test, để binary tự trỏ đúng chỗ khi chạy qua ctest # (ctest không mang theo PNKX_NAV_CORE_CONFIG_DIR hay LD_LIBRARY_PATH của shell). target_compile_definitions(${test_name} PRIVATE MISSION_ADAPTERS_TEST_CONFIG_DIR="${CMAKE_CURRENT_SOURCE_DIR}/test/config" MISSION_ADAPTERS_TEST_LIBRARY_DIR="${CATKIN_DEVEL_PREFIX}/lib" ) endif() endforeach() endif()