• Ros Nodelet 高速通信 单独节点编写


    理解Nodelet

    ROS引入了Nodelet机制,通过共享指针实现了在多算法、多节点间的零拷贝传输。

    ROS通过Nodelet管理器NodeletInterface管理Nodelet,

    并通过ROS的pluglib插件机制实现动态加载Nodelet。

    Nodelet管理器拥有一个可供所有Nodelet使用的线程池,

    线程池的数量通过参数num_worker_threads设置,默认为4。

    Nodelet作为线程出现。

    使用getNodeHandle()、getPrivateNodeHandle()则回调是串行的,

    使用getMTNodeHandle()、getMTPrivateNodeHandle()则回调是基于线程池并行。

    加载nodelet

    两种加载途径(命令行、Launch),三种加载方式(manager、load、standalone )

     作为管理器加载节点  manager

    1. $ nodelet manager
    2. "nodelet" type="nodelet" name="example_manager" args="manager" output="screen" >
    3. "num_worker_threads" type="int" value="8"/>

     在管理器上加载节点  load

    1. $nodelet load pkg/Type 管理器名
    2. "nodelet" type="nodelet" name="nodeletTalker" args="load example_nodelet/NodeletTalker example_manager" output="screen">
    3. "value" type="double" value="10"/>

     按照单例模式,在管理器上加载节点  standalone

    1. $ nodelet standalone pkg/Type
    2. "nodelet" type="nodelet" name="nodeletTalker" args="standalone example_nodelet/NodeletTalker example_manager" output="screen">
    3. "value" type="double" value="10"/>

    共享指针

    共享指针typedef boost::shared_ptr< ::std_msgs::String > StringPtr;

    1. ros::Publisher pub = nh.advertise("nodelet_topic", 5);
    2. std_msgs::StringPtr str(new std_msgs::String); // 声明指针把数据给他
    3. str->data = "hello world"; // 将数据写入
    4. pub.publish(str); // 发布数据

    Nodelet插件描述脚本

    library path标签 :动态库的相对路径;

    class 标签描述了由库提供的类。

    name标签:类的查找名称(名字空间名/类名)。

    供pluginlib工具用作插件的标识符;type标签:类型;

    base_class_type:基类的类型;

    description 标签:类的描述和它能做什么。

    1. "lib/libexampleNodelet">
    2. <class name="example_nodelet/NodeletTalker" type="example_nodelet::NodeletTalker"
    3. base_class_type="nodelet::Nodelet">
    4. nodeletTalker
    5. class>
    6. <class name="example_nodelet/NodeletListener" type="example_nodelet::NodeletListener" base_class_type="nodelet::Nodelet">
    7. NodeletListener
    8. class>

    查看插件是否可用:rosrun nodelet declared_nodelets

    关键编译配置

    1.  package.xml配置
    2. nodelet
    3. "${prefix}/nodelet_description.xml"/>
    4.  CMakeLists.txt配置
    5. catkin_package(
    6. LIBRARIES exampleNodelet
    7. CATKIN_DEPENDS roscpp rospy nodelet std_msgs
    8. )
    9. include_directories(
    10. include
    11. ${catkin_INCLUDE_DIRS}
    12. )
    13. add_library(exampleNodelet src/nodelet_plugins.cpp)

    实现Nodelet步骤

    步骤1  定义继承nodelet::Nodelet的Nodelet插件    .cpp

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. namespace example_nodelet{ // 定义空间
    7. void NodeletTalker::onInit(){
    8. NODELET_INFO("NodeletTalker onInit");
    9. std_msgs::Float64Ptr input(new std_msgs::Float64()); // 共享指针
    10. ros::NodeHandle& nh = getMTNodeHandle(); // 获得句柄
    11. nh.getParam("value",value); // 获得句柄参数
    12. pub = nh.advertise("test", 100); // 创建接受节点
    13. ros::Rate loop_rate(1); // 发布Hz
    14. while (ros::ok()) //
    15. {
    16. /* code */
    17. input->data = value + 10;
    18. pub.publish(input);
    19. NODELET_INFO("the NodeletTalker value is %f", input->data);
    20. ros::spinOnce();
    21. loop_rate.sleep();
    22. value+= 10;
    23. }
    24. }
    25. void NodeletListener::onInit(){
    26. NODELET_INFO("NodeletListener onInit");
    27. ros::NodeHandle& nh = getMTNodeHandle();
    28. sub = nh.subscribe("test", 100, &NodeletListener::callback, this);
    29. }
    30. void NodeletListener::callback(const std_msgs::Float64::ConstPtr& input){
    31. std_msgs::Float64Ptr output(new std_msgs::Float64());
    32. output->data = input->data + 5;
    33. NODELET_INFO("the NodeletListener value is %f", output->data);
    34. }
    35. }
    36. PLUGINLIB_EXPORT_CLASS(example_nodelet::NodeletListener, nodelet::Nodelet); //声明插件
    37. PLUGINLIB_EXPORT_CLASS(example_nodelet::NodeletTalker, nodelet::Nodelet); //声明插件

    头.h 文件.

    1. #include
    2. #include
    3. #include
    4. namespace example_nodelet{
    5. class NodeletTalker: public nodelet::Nodelet // 继承节点
    6. {
    7. private:
    8. /* data 发布者 */
    9. double value = 10;
    10. ros::Publisher pub;
    11. virtual void onInit();
    12. };
    13. class NodeletListener: public nodelet::Nodelet
    14. {
    15. private:
    16. /* data 订阅者 */
    17. ros::Subscriber sub;
    18. virtual void onInit(); // 初始化函数
    19. void callback(const std_msgs::Float64::ConstPtr& input); // 回调
    20. };
    21. }

    步骤2  重载插件的onInit()方法

    步骤3  声明Nodelet插件

    步骤4  创建Nodelet插件描述脚本

    步骤5  编写Launch文件

    1. "nodelet" type="nodelet" name="example_manager" args="manager" output="screen" >
    2. "num_worker_threads" type="int" value="8"/>
    3. "nodelet" type="nodelet" name="nodeletListener"
    4. args="standalone example_nodelet/NodeletListener example_manager" output="screen">
    5. "nodelet" type="nodelet" name="nodeletTalker"
    6. args="standalone example_nodelet/NodeletTalker example_manager" output="screen">
    7. "value" type="double" value="10"/>

    步骤6  package.xml、CMakeLists.txt配置

    1. cmake_minimum_required(VERSION 3.0.2)
    2. project(example_6)
    3. ## Compile as C++11, supported in ROS Kinetic and newer
    4. # add_compile_options(-std=c++11)
    5. ## Find catkin macros and libraries
    6. ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
    7. ## is used, also find other catkin packages
    8. find_package(catkin REQUIRED COMPONENTS
    9. roscpp
    10. rospy
    11. nodelet
    12. std_msgs
    13. )
    14. ## System dependencies are found with CMake's conventions
    15. # find_package(Boost REQUIRED COMPONENTS system)
    16. ## Uncomment this if the package has a setup.py. This macro ensures
    17. ## modules and global scripts declared therein get installed
    18. ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
    19. # catkin_python_setup()
    20. ################################################
    21. ## Declare ROS messages, services and actions ##
    22. ################################################
    23. ## To declare and build messages, services or actions from within this
    24. ## package, follow these steps:
    25. ## * Let MSG_DEP_SET be the set of packages whose message types you use in
    26. ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
    27. ## * In the file package.xml:
    28. ## * add a build_depend tag for "message_generation"
    29. ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
    30. ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
    31. ## but can be declared for certainty nonetheless:
    32. ## * add a exec_depend tag for "message_runtime"
    33. ## * In this file (CMakeLists.txt):
    34. ## * add "message_generation" and every package in MSG_DEP_SET to
    35. ## find_package(catkin REQUIRED COMPONENTS ...)
    36. ## * add "message_runtime" and every package in MSG_DEP_SET to
    37. ## catkin_package(CATKIN_DEPENDS ...)
    38. ## * uncomment the add_*_files sections below as needed
    39. ## and list every .msg/.srv/.action file to be processed
    40. ## * uncomment the generate_messages entry below
    41. ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
    42. ## Generate messages in the 'msg' folder
    43. # add_message_files(
    44. # FILES
    45. # Message1.msg
    46. # Message2.msg
    47. # )
    48. ## Generate services in the 'srv' folder
    49. # add_service_files(
    50. # FILES
    51. # Service1.srv
    52. # Service2.srv
    53. # )
    54. ## Generate actions in the 'action' folder
    55. # add_action_files(
    56. # FILES
    57. # Action1.action
    58. # Action2.action
    59. # )
    60. ## Generate added messages and services with any dependencies listed here
    61. # generate_messages(
    62. # DEPENDENCIES
    63. # std_msgs
    64. # )
    65. ################################################
    66. ## Declare ROS dynamic reconfigure parameters ##
    67. ################################################
    68. ## To declare and build dynamic reconfigure parameters within this
    69. ## package, follow these steps:
    70. ## * In the file package.xml:
    71. ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
    72. ## * In this file (CMakeLists.txt):
    73. ## * add "dynamic_reconfigure" to
    74. ## find_package(catkin REQUIRED COMPONENTS ...)
    75. ## * uncomment the "generate_dynamic_reconfigure_options" section below
    76. ## and list every .cfg file to be processed
    77. ## Generate dynamic reconfigure parameters in the 'cfg' folder
    78. # generate_dynamic_reconfigure_options(
    79. # cfg/DynReconf1.cfg
    80. # cfg/DynReconf2.cfg
    81. # )
    82. ###################################
    83. ## catkin specific configuration ##
    84. ###################################
    85. ## The catkin_package macro generates cmake config files for your package
    86. ## Declare things to be passed to dependent projects
    87. ## INCLUDE_DIRS: uncomment this if your package contains header files
    88. ## LIBRARIES: libraries you create in this project that dependent projects also need
    89. ## CATKIN_DEPENDS: catkin_packages dependent projects also need
    90. ## DEPENDS: system dependencies of this project that dependent projects also need
    91. catkin_package(
    92. # INCLUDE_DIRS include
    93. LIBRARIES exampleNodelet
    94. CATKIN_DEPENDS roscpp rospy nodelet std_msgs
    95. # DEPENDS system_lib
    96. )
    97. ###########
    98. ## Build ##
    99. ###########
    100. ## Specify additional locations of header files
    101. ## Your package locations should be listed before other locations
    102. include_directories(
    103. include
    104. ${catkin_INCLUDE_DIRS}
    105. )
    106. ## Declare a C++ library
    107. # add_library(${PROJECT_NAME}
    108. # src/${PROJECT_NAME}/example_6.cpp
    109. # )
    110. ## Add cmake target dependencies of the library
    111. ## as an example, code may need to be generated before libraries
    112. ## either from message generation or dynamic reconfigure
    113. # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    114. ## Declare a C++ executable
    115. ## With catkin_make all packages are built within a single CMake context
    116. ## The recommended prefix ensures that target names across packages don't collide
    117. # add_executable(${PROJECT_NAME}_node src/example_6_node.cpp)
    118. ## Rename C++ executable without prefix
    119. ## The above recommended prefix causes long target names, the following renames the
    120. ## target back to the shorter version for ease of user use
    121. ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
    122. # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
    123. ## Add cmake target dependencies of the executable
    124. ## same as for the library above
    125. # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    126. ## Specify libraries to link a library or executable target against
    127. if(CMAKE_BUILD_TYPE STREQUAL DEBUG)
    128. add_library(exampleNodelet src/nodelet_plugins.cpp)
    129. target_link_libraries(exampleNodelet
    130. ${catkin_LIBRARIES}
    131. )
    132. endif()
    133. #############
    134. ## Install ##
    135. #############
    136. # all install targets should use catkin DESTINATION variables
    137. # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
    138. ## Mark executable scripts (Python etc.) for installation
    139. ## in contrast to setup.py, you can choose the destination
    140. # catkin_install_python(PROGRAMS
    141. # scripts/my_python_script
    142. # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    143. # )
    144. ## Mark executables for installation
    145. ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
    146. # install(TARGETS ${PROJECT_NAME}_node
    147. # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    148. # )
    149. ## Mark libraries for installation
    150. ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
    151. # install(TARGETS ${PROJECT_NAME}
    152. # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    153. # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    154. # RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
    155. # )
    156. ## Mark cpp header files for installation
    157. # install(DIRECTORY include/${PROJECT_NAME}/
    158. # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
    159. # FILES_MATCHING PATTERN "*.h"
    160. # PATTERN ".svn" EXCLUDE
    161. # )
    162. ## Mark other files for installation (e.g. launch and bag files, etc.)
    163. # install(FILES
    164. # # myfile1
    165. # # myfile2
    166. # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
    167. # )
    168. #############
    169. ## Testing ##
    170. #############
    171. ## Add gtest based cpp test target and link libraries
    172. # catkin_add_gtest(${PROJECT_NAME}-test test/test_example_6.cpp)
    173. # if(TARGET ${PROJECT_NAME}-test)
    174. # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
    175. # endif()
    176. ## Add folders to be run by python nosetests
    177. # catkin_add_nosetests(test)

    步骤7  编译执行

     

  • 相关阅读:
    YOLO-V3实时检测实现(opencv+python实现)
    Qt之彻底解决QSpinBox限定范围无效的问题
    进程通信之共享内存
    Matlab:无穷和 NaN
    【JavaScript实现 百元买百鸡问题】
    Linux RPM 构建
    [架构之路-51]:架构师 - 用系统化、结构化思维解决复杂难搞的软件故障问题 - 马克思主义哲学在软件系统中的应用
    生产者消费者问题实践
    【WiFi】WiFi信道(2.4G、5G及5G DFS)及国家码和电话代码和时区对应表
    (九)学习笔记:动手深度学习(多层感知机 + 代码实现)
  • 原文地址:https://blog.csdn.net/weixin_44025389/article/details/126486616