ROS中nodelet的使用


ROS中nodelet的使用

1. 为什么使用nodelet?

Nodelet提供了一种方法,可以在同一台计算机上,在同一个进程内,运行多个算法,且在进程内消息传递时不产生复制成本(zero copy)。在一个node里面,roscpp利用指针传递可以实现在publish和subscribe调用时的零拷贝。为了实现相似的效果,多个nodelets允许将多个类动态加载到同一个node里,同时还提供独立的命名空间,从而使得这些nodelets尽管运行在同一个进程里,但却仍然像单独的node一样工作。也就实现了“在一个进程(node)里运行多个nodelet”的效果。

因此,大通量数据流可能包含多个nodelet,此时若将他们加载到同一个进程里,就可以避免数据拷贝和网络传输。

2. 在ROS工程中使用nodelet

2.1 创建工作空间和程序包

mkdir -p ~/catkin_ar/src

cd catkin_ar/

catkin_make

source devel/setup.sh

cd src

catkin_create_pkg try_nodelet roscpp rospy nodelet std_msgs sensor_msgs cv_bridge image_transport ddynamic_reconfigure

2.2 创建并且编写cpp文件与hpp文件

//try_use.hpp
#pragma once
#include <nodelet/nodelet.h>
#include <ros/ros.h>

namespace try_nodelet
{
    class try_use : public nodelet::Nodelet
    {
    public:
        virtual void onInit();
    };
}
//try_use.cpp
#include <pluginlib/class_list_macros.h>
#include <../include/try_nodelet/try_use.hpp>

PLUGINLIB_EXPORT_CLASS(try_nodelet::try_use,nodelet::Nodelet)

namespace try_nodelet
{
    void try_use::onInit()
    {
        NODELET_DEBUG("Initializing nodelet...");
        ROS_INFO("Nodelet is Ok for test!!");
    }
}

2.3 编写nodelet_plugins.xml

<library path="lib/libtry_nodelet">
    
<!--上面这个try_nodelet是包的名字,下面的那个是命名空间的名字-->
    
  <class name="try_nodelet/try_use" type="try_nodelet::try_use" base_class_type="nodelet::Nodelet">
  <description>
  Trying to use nodelet in ROS.
  </description>
  </class>
</library>

2.4 修改CMakeLists.txt与package.xml

修改CMakeLists.txt

cmake_minimum_required(VERSION 3.0.2)
project(try_nodelet)

add_compile_options(-std=c++11)
#上面这个最好加上,否则可能会编译失败

find_package(catkin REQUIRED COMPONENTS
  cv_bridge
  ddynamic_reconfigure
  image_transport
  nodelet
  roscpp
  rospy
  sensor_msgs
  std_msgs
)

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES try_nodelet
  CATKIN_DEPENDS cv_bridge ddynamic_reconfigure image_transport nodelet roscpp rospy sensor_msgs std_msgs
#  DEPENDS system_lib
)

include_directories(
   include
  ${catkin_INCLUDE_DIRS}
)

add_library(${PROJECT_NAME} 
    src/try_use.cpp
)

add_dependencies(
    ${PROJECT_NAME} 
    ${${PROJECT_NAME}_EXPORTED_TARGETS} 
    ${catkin_EXPORTED_TARGETS}
)

修改package.xml

<?xml version="1.0"?>
<package format="2">
  <name>try_nodelet</name>
  <version>0.0.0</version>
  <description>The try_nodelet package</description>

  <maintainer email="npu-lqx@todo.todo">npu-lqx</maintainer>

  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>cv_bridge</build_depend>
  <build_depend>ddynamic_reconfigure</build_depend>
  <build_depend>image_transport</build_depend>
  <build_depend>nodelet</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>cv_bridge</build_export_depend>
  <build_export_depend>ddynamic_reconfigure</build_export_depend>
  <build_export_depend>image_transport</build_export_depend>
  <build_export_depend>nodelet</build_export_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>sensor_msgs</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>cv_bridge</exec_depend>
  <exec_depend>ddynamic_reconfigure</exec_depend>
  <exec_depend>image_transport</exec_depend>
  <exec_depend>nodelet</exec_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>sensor_msgs</exec_depend>
  <exec_depend>std_msgs</exec_depend>

  <export>
    <nodelet plugin="${prefix}/nodelet_plugins.xml" />
  </export>

</package>

3.启动ROS节点

3.1 编写launch文件进行快速启动

新建一个launch文件夹,并在文件夹中新建一个start.launch文件

<launch>
  <node pkg="nodelet" type="nodelet" name="standalone_nodelet"  args="manager" output="screen"/>
  <node pkg="nodelet" type="nodelet" name="using_nodelet" args="load try_nodelet/try_use standalone_nodelet" output="screen">
  </node>
</launch>

3.2 通过命令行运行

#终端1
roscore
#终端2
rosrun nodelet nodelet manager __name:=nodelet_manager
#终端3
rosrun nodelet nodelet load try_nodelet/try_use nodelet_manager __name:=using_nodelet

注意,如果这里报错“According to the loaded plugin descriptions the class try_nodelet/try_use with base class type nodelet::Nodelet does not exist.” 一般是因为运行manager的窗口(终端2)没有source

所以要么一开始就把source写进配置文件中,要么就每个相关的窗口都要source,这样能够避免很多问题,也方便自己找到程序的bug所在。

4.将已有的ROS工程改写为nodelet

待补充~


文章作者: Immortalqx
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Immortalqx !
评论
  目录