ROS节点是什么 如何诞生的

发布时间:2023-09-14  

** 一个节点的诞生**

在建立连接之前,首先要有节点。

节点就是一个独立的程序,它运行起来后就是一个普通的进程,与计算机中其它的进程并没有太大区别。

一个问题是:中为什么把一个独立的程序称为“节点”

这是因为ROS沿用了计算机中“节点”的概念。

在一个网络中,例如互联网,每一个上网的计算机就是一个节点。前面我们看到的客户端、服务器这样的称呼,也是从计算机网络中借用的。

下面来看一下节点是如何诞生的。我们在第一次使用ROS时,一般都会照着官方编写一个talker和一个listener节点,以熟悉ROS的使用方法。

我们以talker为例,它的部分代码如下。

#include "ros/ros.h"
int main(int argc, char **argv)
{
  /* You must call one of the versions of ros::init() befe using any other part of the ROS system. */
  ros::init(argc, argv, "talker");
  ros::NodeHandle n;

main函数里首先调用了init()函数初始化一个节点,该函数的定义在init.cpp文件中。

当我们的程序运行到init()函数时,一个节点就呱呱坠地了。

而且在出生的同时我们还顺道给他起好了名字,也就是"talker"。

名字是随便起的,但是起名是必须的。

我们进入init()函数里看看它做了什么,代码如下,看上去还是挺复杂的。它初始化了一个叫g_global_queue的数据,它的类型是CallbkQueuePtr。

这是个相当重要的类,叫“回调队列”,后面还会见到它。init()函数还调用了network、master、this_node、file_log、pa这几个命名空间里的init初始化函数各自实现一些变量的初始化,这些变量都以g开头,例如g_host、g_uri,用来表明它们是全局变量。

其中,network::init完成节点主机名、IP地址等的初始化,master::init获取master的URI、主机号和号。

this_node::init定义节点的命名空间和节点的名字,没错,把我们给节点起的名字就存储在这里。file_log::init初始化日志文件的路径。

void init(const M_string& remapngs, const std::string& name, uint32_t opons)
{
  if (!g_atexit_registered) {
    g_atexit_registered = true;
    atexit(atexitCallback);
  }
  if (!g_global_queue) {
    g_global_queue.reset(new CallbackQueue);
  }
  if (!g_initialized) {
    g_init_options = options;
    g_ok = true;
    ROSCONSOLE_AUTOINIT;
    // Disable SIGPIPE
#ifndef WIN32
    signal(SIGPIPE, SIG_IGN);
#else
    WSADATA wsaData;
    Wtartup(MAKEWORD(2, 0), &wsaData);
#endif
    check_ipv6_environment();
    network::init(remappings);
    master::init(remappings);
    // names:: namespace is initialized by this_node
    this_node::init(name, remappings, options);
    file_log::init(remappings);
    param::init(remappings);
    g_initialized = true;
  }
}

完成初始化以后,就进入下一步ros::NodeHandle n定义句柄。

我们再进入node_handle.cpp文件,发现构造函数NodeHandle::NodeHandle调用了自己的construct函数。然后,顺藤摸瓜找到construct函数,它里面又调用了ros::start()函数。

没错,我们又绕回到了init.cpp文件。

ros::start()函数主要实例化了几个重要的类,如下。

完成实例化后马上又调用了各自的start()函数,启动相应的动作。

这些都做完了以后就可以发布或订阅消息了。

一个节点的故事暂时就到这了。

TopicManager::instance()- >start();
ServeManager::instance()- >start();
ConnectionManager::instance()- >start();
PollManager::instance()- >start();
XMLRPCManager::instance()- >start();
文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>