ROS節點的初始化及退出詳解(ros::init、SIGINT、ros::ok、ros::NodeHandle)

但願你們收藏:html

本文更新地址:https://haoqchen.site/2018/04/28/ROS-node-init/node

左側專欄還在更新其餘ROS實用技巧哦,關注一波?c++

不少ROS新手編寫節點的時候都不知道要怎麼才能Ctrl+c退出,根本都沒有注意到一個節點的生命流程,看完你就懂了~~git

先上程序:github

完整版工程已經上傳到github:https://github.com/HaoQChen/init_shutdown_test,下載完麻煩你們點個贊網絡

全部知識點都寫在註釋裏了,請慢慢閱讀,每一個語句前面的註釋是ROS官方註釋,後面的註釋則是做者本身寫的app

#include "ros/ros.h"
#include <signal.h>

void MySigintHandler(int sig)
{
	//這裏主要進行退出前的數據保存、內存清理、告知其餘節點等工做
	ROS_INFO("shutting down!");
	ros::shutdown();
}

int main(int argc, char** argv){
//ros::init()
	/**
	  * The ros::init() function needs to see argc and argv so that it can perform
	  * any ROS arguments and name remapping that were provided at the command line. For programmatic
	  * remappings you can use a different version of init() which takes remappings
	  * directly, but for most command-line programs, passing argc and argv is the easiest
	  * way to do it.  The third argument to init() is the name of the node.
	  *
	  * You must call one of the versions of ros::init() before using any other
	  * part of the ROS system.
	*/
	ros::init(argc, argv, "ist_node");
	//初始化節點名字必須在最前面,若是ROS系統中出現重名,則以前的節點會被自動關閉
	//若是想要多個重名節點而不報錯,能夠在init中添加ros::init_options::AnonymousName參數
	//該參數會在原有節點名字的後面添加一些隨機數來使每一個節點獨一無二
	//ros::init(argc, argv, "my_node_name", ros::init_options::AnonymousName);

//ros::NodeHandle
	/**
	  * NodeHandle is the main access point to communications with the ROS system.
	  * The first NodeHandle constructed will fully initialize this node, and the last
	  * NodeHandle destructed will call ros::shutdown() to close down the node.
	*/
	ros::NodeHandle h_node;
	//獲取節點的句柄,init是初始化節點,這個是Starting the node
	//若是不想經過對象的生命週期來管理節點的開始和結束,你能夠經過ros::start()和ros::shutdown() 來本身管理節點。
	
	ros::Rate loop_rate(1);
	//loop once per second
	//Cannot use before the first NodeHandle has been created or ros::start() has been called.

//shut down
	signal(SIGINT, MySigintHandler);
	//覆蓋原來的Ctrl+C中斷函數,原來的只會調用ros::shutdown()
	//爲你關閉節點相關的subscriptions, publications, service calls, and service servers,退出進程

//run status
	int sec = 0;
	while(ros::ok() && sec++ < 5){
		loop_rate.sleep();
		ROS_INFO("ROS is ok!");
		ros::spinOnce();
	}
	//ros::ok()返回false,表明可能發生瞭如下事件
		//1.SIGINT被觸發(Ctrl-C)調用了ros::shutdown()
		//2.被另外一同名節點踢出 ROS 網絡
		//3.ros::shutdown()被程序的另外一部分調用
		//4.節點中的全部ros::NodeHandles 都已經被銷燬
	//ros::isShuttingDown():一旦ros::shutdown()被調用(注意是剛開始調用,而不是調用完畢),就返回true
	//通常建議用ros::ok(),特殊狀況能夠用ros::isShuttingDown()

	ROS_INFO("Node exit");
	printf("Process exit\n");
	return 0;
}

下載工程運行後能夠看到,終端每隔一秒會輸出ROS is ok!的信息ide

 

  1. 若是5秒以內沒有按下Ctrl+C正常退出,則會正常退出。輸出:

  1. 若是5秒內按下了Ctrl+C,則會調用MySigintHandler,而後ros::shutdown();從終端信息咱們能夠看到,調用ros::shutdown();後,全部ROS服務已經不可使用,連ROS_INFO也是不能用的,輸出信息失敗。因此在程序中要密切注意退出部分的程序不要使用ROS的東西。

 

參考:

ROS官網:編寫簡單的消息發佈器和訂閱器 (C++)函數

ROS官網:roscppOverviewInitialization and Shutdownoop

https://blog.csdn.net/wuguangbin1230/article/details/76889753

http://blog.sina.com.cn/s/blog_8a2281f70102xi2v.html

相關文章
相關標籤/搜索