** 一個節點的誕生**
在建立連接之前,首先要有節點。
節點就是一個獨立的程序,它運行起來后就是一個普通的進程,與計算機中其它的進程并沒有太大區別。
一個問題是:ROS中為什么把一個獨立的程序稱為“節點”
這是因為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() before 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的數據,它的類型是CallbackQueuePtr。
這是個相當重要的類,叫“回調隊列”,后面還會見到它。init()函數還調用了network、master、this_node、file_log、param這幾個命名空間里的init初始化函數各自實現一些變量的初始化,這些變量都以g開頭,例如g_host、g_uri,用來表明它們是全局變量。
其中,network::init完成節點主機名、IP地址等的初始化,master::init獲取master的URI、主機號和端口號。
this_node::init定義節點的命名空間和節點的名字,沒錯,把我們給節點起的名字就存儲在這里。file_log::init初始化日志文件的路徑。
void init(const M_string& remappings, const std::string& name, uint32_t options)
{
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;
WSAStartup(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();
ServiceManager::instance()- >start();
ConnectionManager::instance()- >start();
PollManager::instance()- >start();
XMLRPCManager::instance()- >start();
-
計算機
+關注
關注
19文章
7489瀏覽量
87869 -
節點
+關注
關注
0文章
218瀏覽量
24422 -
網絡
+關注
關注
14文章
7557瀏覽量
88737 -
ROS
+關注
關注
1文章
278瀏覽量
17004
發布評論請先 登錄
相關推薦
評論