但愿你们收藏: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
- 若是5秒以内没有按下Ctrl+C正常退出,则会正常退出。输出:
- 若是5秒内按下了Ctrl+C,则会调用MySigintHandler,而后ros::shutdown();从终端信息咱们能够看到,调用ros::shutdown();后,全部ROS服务已经不可使用,连ROS_INFO也是不能用的,输出信息失败。因此在程序中要密切注意退出部分的程序不要使用ROS的东西。
参考:
ROS官网:roscppOverviewInitialization and Shutdownoop
https://blog.csdn.net/wuguangbin1230/article/details/76889753