乐于分享
好东西不私藏

Ros2 源码中如何知道当前使用哪个 DDS 中间件

Ros2 源码中如何知道当前使用哪个 DDS 中间件
一,这里只考虑默认情况
    默认情况就是直接 colcon build 的情况,不设置 RMW_IMPLEMENTATION 环境变量。
二,定义一个获取默认 dds 实现的 camke 宏
     定义这个宏的文件是:
src/ros2/rmw/rmw_implementation_cmake/cmake/get_default_rmw_implementation.cmake
    宏定义如下:
# :param var: the output variable name containing the package name# :type var: string#   var 是个出参,#  调用 get_default_rmw_implementation,返回结果存储到 var 里。macro(get_default_rmw_implementation var)  ##  ## get_available_rmw_implementations  ## 这个东西获取一个中间件的列表  ## 存在 _middleware_implementations 这里  ## 它的定义在  ## src/ros2/rmw/rmw_implementation_cmake/cmake/get_available_rmw_implementations.cmake  ##   get_available_rmw_implementations(_middleware_implementations)  if(_middleware_implementations STREQUAL "")    message(FATAL_ERROR "Could not find any ROS middleware implementation.")  endif()  # option()  if("${RMW_IMPLEMENTATION}" STREQUAL "" AND    "$ENV{RMW_IMPLEMENTATION}" STREQUAL ""  )    # prefer FastDDS, otherwise first in alphabetical order    # 如果列表里有 rmw_fastrtps_cpp,就把它作为默认了。    list(FIND _middleware_implementations "rmw_fastrtps_cpp" _index)    if(NOT _index EQUAL -1)      list(GET _middleware_implementations ${_index} _middleware_implementation)    else()      list(GET _middleware_implementations 0 _middleware_implementation)    endif()  else()    if(NOT "${RMW_IMPLEMENTATION}" STREQUAL "")      set(_middleware_implementation "${RMW_IMPLEMENTATION}")    else()      set(_middleware_implementation "$ENV{RMW_IMPLEMENTATION}")    endif()    # persist implementation decision in cache    # if it was not determined dynamically    set(      RMW_IMPLEMENTATION "${_middleware_implementation}"      CACHE STRING "Select ROS middleware implementation to link against" FORCE    )  endif()  # verify that the selection one is available  list(FIND _middleware_implementations "${_middleware_implementation}" _index)  if(_index EQUAL -1)    string(REPLACE ";" ", " _middleware_implementations_string "${_middleware_implementations}")    message(FATAL_ERROR      "Could not find ROS middleware implementation '${_middleware_implementation}'. "      "Choose one of the following: ${_middleware_implementations_string}")  endif()  find_package("${_middleware_implementation}" REQUIRED)  ## 把默认中间件的名字传出去  set(${var} ${_middleware_implementation})endmacro()
三,把默认 dds 写入环境变量 RMW_IMPLEMENTATION
    文件路径: 
src/ros2/rmw_implementation/rmw_implementation/CMakeLists.txt

    相关代码:

get_default_rmw_implementation(RMW_IMPLEMENTATION)message(STATUS "")message(STATUS "Default rmw implementation: '${RMW_IMPLEMENTATION}'")message(STATUS "")
四,在运行时读取 RMW_IMPLEMENTATION 配置
    文件路径:
src/ros2/rmw_implementation/rmw_implementation/src/functions.cpp
    相关代码:
std::shared_ptr<rcpputils::SharedLibrary>load_library(){  // The logic to pick the RMW library to load goes as follows:  //  // 1. If the user specified the library to use via the RMW_IMPLEMENTATION  //    environment variable, try to load only that library.  // 2. Otherwise, try to load the default RMW implementation.  // 3. If that fails, try loading all other implementations available in turn  //    until one succeeds or we run out of options.      std::string env_var;      try {        env_var = rcpputils::get_env_var("RMW_IMPLEMENTATION");      } catch (const std::exception & e) {        RMW_SET_ERROR_MSG_WITH_FORMAT_STRING(          "failed to fetch RMW_IMPLEMENTATION "          "from environment due to %s", e.what());        return nullptr;      }      /// other code  }
至此,Ros2 获取当前使用的 dds 中间件的链路打通。
就这样。