您的当前位置:首页正文

nodelet的理解

2020-06-03 来源:意榕旅游网
nodelet的理解

1.介绍

nodelet包可以为在相同进程中的多个算法之间实现零拷贝的传输⽅式。

这个包也提供了实现⼀个nodelet所需的nodelet基类以及⽤于实例化nodelet的NodeletLoader类。Source: git (branch: indigo-devel)

Nodelets旨在提供⼀种在单机器单进程运⾏多个算法⽽不会在进程中传递消息时产⽣复制成本的⽅法。roscpp具有在同⼀节点内的发布和订阅调⽤之间进⾏零拷贝指针传递的优化。

为了做到这⼀点,nodelet允许将类动态加载到同⼀个节点,然⽽它们提供了简单的单独命名空间,使得尽管nodelet在同⼀个进程中,它仍然像⼀个独⽴的节点

这进⼀步扩展了,它在运⾏时使⽤pluginlib是动态可加载的。2.应⽤

⾼吞吐量的数据流可以由许多节点组成,然后加载到同⼀进程,以避免复制和⽹络流量。3.设计⽬标

使⽤现有的C++ ROS接⼝。

允许节点之间的数据的零拷贝传递

动态加载为插件以打破构建时间依赖性位置透明,除了性能改进

节点或节点中编写代码将有最⼩差异。4.技术

定义将⽤于动态加载的基类nodelet :: Nodelet。

所有nodelet都将继承这个基类,并且可以使⽤pluginlib进⾏动态加载。

它将提供命名空间,⾃动重映射参数和参数,就像它们是第⼀个类节点⼀样。将有⼀个nodelet_manager进程,⼀个或多个nodelet可以加载到其中。

它们之间的任何通信都可以使⽤带有boost共享指针的零拷贝roscpp发布调⽤。5.基本⽤法

nodelet usage:

nodelet load pkg/Type manager - Launch a nodelet of type pkg/Type on manager managernodelet standalone pkg/Type - Launch a nodelet of type pkg/Type in a standalone nodenodelet unload name manager - Unload a nodelet a nodelet by name from managernodelet manager - Launch a nodelet manager node对于命令⾏和启动⽂件⽰例,6.API

1)Nodelet基类

公共⽅法:

//动态加载时使⽤的默认构造函数 Nodelet()

//这个⽅法是⼀个描述nodelet如何启动。

//参数是管理器启动本节点所需的参数。这将初始化nodelet基类,然后调⽤⼦类的onInit()⽅法。

void init (const std::string& name, const ros::M_string& remapping_args, const std::vector& my_argv); ⼦类中使⽤的受保护成员和⽅法:

std::string getName() //Get the name of the nodelet

ros::NodeHandle& getNodeHandle () // Get the node handle (provides this nodelets custom remappings and name)

ros::NodeHandle& getPrivateNodeHandle () // Get the private node handle (provides this nodelets custom remappings in its private namespace)

ros::NodeHandle& getMTNodeHandle () // Get the node handle with the Multi Threaded callback queue. (provides this nodelets custom remappings and name)

ros::NodeHandle& getMTPrivateNodeHandle () // Get the private node handle with the Multi Threaded callback queue. (provides this nodelets custom remappings in its private namespace)ros::CallbackQueue& getMTCallbackQueue () // Get the callback queue (threadpool available from the manager)

std::vector getMyArgv() // Get command line arguments to the nodelet stripped of ROS and nodelet specific args.

⽤于在⼦类中启动ROS API的初始化⽅法:

virtual void onInit () = 0 //Virtual and must be overridden by subclass. All initialization of the ROS infrastructure must be put into this function.

7.NODELET ROSCONSOLE宏

这些Nodelet封装是rosconsole宏。

它们包括详细程度级别DEBUG,INFO,WARN,ERROR和FATAL。这些宏只会在nodelet⽅法中编译。

它们通过在运⾏的nodelet名称中设置命名的⽇志记录器来操作,以便您可以区分在运⾏的同⼀管理器下的两个相同类型的节点的输出。他们也有优势,你可以转⼀个具体nodelet进⼊调试,⽽不是所有特定类型的节点。⽰例代码

#include \"nodelet/nodelet.h\"

//... inside a nodelet method

NODELET_DEBUG(\"My debug statement\")

NODELET_DEBUG_STREAM(\"my debug statement \" << (double) 1.0)NODELET_DEBUG_COND( 1 == 1, \"my debug_statement\")

NODELET_DEBUG_STREAM_COND( 1 == 1, \"my debug statement \" << (double) 1.0)8.从Nodelet发布

如果希望no-copy pub/sub⼯作,您必须将消息发布为shared_ptr。有关更多详细信息,请参阅。9.线程模型

节点管理器具有线程池,该线程池在管理器内运⾏的所有节点之间共享,这由参数“num_worker_threads”设置。在nodelet中运⾏的代码中有两种可能的线程API。默认线程模型有⼀个线程⽤于所有回调。还有⼀个多线程API。1)onInit,这个⽅法在init上调⽤,不应该阻塞或做重要的⼯作。

2)Single Threaded API单线程API,使⽤⽅法getNodeHandle()和getPrivateNodeHandle()将保证所有回调都并⾏到达。3)Multi Threaded API多线程API,使⽤⽅法getMTNodeHandle()和getMTPrivateNodeHandle()回调将分布在管理器线程池。4)Additional Threads其他线程,它是节点创建⾃⼰的线程进⾏操作的有效操作。这些线程应该在析构函数中正确清理。

5)Thread Sharing线程共享,所有nodelet共享管理器的线程池。如果nodelet阻塞线程,它们可能会阻⽌其他nodelet获得回调。确保管理器配置了⾜够的线程以防⽌阻塞。

注意:即使单个线程的节点句柄也可以每个节点使⽤池的1个线程。

因篇幅问题不能全部显示,请点此查看更多更全内容