· roscpp/Overview/Initialization and Shutdown
初始化
roscpp 节点有两种初始化级别:
1. 通过调用其中一个ros :: init()函数来初始化节点。这为ROS提供了命令行参数,并允许您命名节点并指定其他选项。
2. 启动节点通常是通过创建ros :: NodeHandle来完成的,但在高级情况下可以通过不同的方式来完成。
1初始化roscpp节点
另请参阅:ros :: init()代码API
在调用节点中的任何其他roscpp函数之前,您必须调用其中一个ros :: init()函数。两个最常见的init()调用是:
1ros :: init(argc,argv,“ my_node_name ”);
和
1ros :: init(argc,argv,“ my_node_name ”,ros :: init_options :: AnonymousName);
一般来说,ros :: init()的形式符合:
1voidros::init(<commandlineorremappingarguments>, std::stringnode_name, uint32_toptions);
让我们依次讨论这些论点:
argc和argv
ROS使用这些来解析来自命令行的重新映射参数。并修改它们,以便它们不再包含任何重新映射参数,因此,如果在处理命令行之前调用ros :: init(),则不需要自己跳过这些参数。
NODE_NAME
这是将被分配给您的节点的名称,除非它被重新映射参数之一覆盖。节点名称在ROS系统中必须是唯一的。如果第二个节点以与第一个节点相同的名称启动,则第一个节点将自动关闭。如果希望多个同一节点运行而不必担心它们的唯一命名,可以使用下面描述的init_options :: AnonymousName选项。
Options
这是一个可选参数,可以让你指定某些改变roscpp行为的选项。该字段是一个位字段,因此可以指定多个选项。这些选项在“ 初始化选项”部分进行了描述。
还有其他形式的ros :: init()不采用argc / argv,而是采用显式重映射选项。具体来说,有一些版本需要std :: map <std:: string,std :: string>和std :: vector<std :: pair <std :: string,std :: string>>。
初始化节点只需读取命令行参数和环境即可找出节点名称、名称空间和重新映射等内容。它并没有联系master。这可以让你在调用ros :: init()检查master的状态之后使用ros :: master :: check()和其他的ROS函数。该节点只有在启动后才会完全启动,这在启动roscpp节点部分进行了描述。
1.1.1初始化选项
另请参阅:ros :: init_options代码API
· ROS :: init_options :: NoSigintHandler
不要安装SIGINT处理程序。在这种情况下,您应该安装自己的SIGINT处理程序,以确保该节点在退出时正确关闭。请注意,SIGINT的默认操作往往是终止进程,因此如果您要执行自己的SIGTERM处理,则还必须使用此选项。
ROS :: init_options :: AnonymousName
匿名化节点名称。将一个随机数添加到节点名称的末尾,以使其具有唯一性。
ROS :: init_options :: NoRosout
不要将rosconsole输出广播到/ rosout主题。
1.1.2访问您的命令行参数
如上所述,使用argc和argv 调用ros :: init()将从命令行中删除ROS参数。如果你需要在调用ros :: init()之前解析命令行,你可以调用(ROS 0.10中的new)ros :: removeROSArgs()函数。
1.2启动roscpp节点
启动roscpp节点的最常见方法是创建一个ros :: NodeHandle:
1ros :: NodeHandle nh ;
当第一个ros :: NodeHandle被创建时,它会调用ros :: start(),当最后一个ros :: NodeHandle被销毁时,它会调用ros :: shutdown()。如果你想手动管理节点的生命周期,你可以自己调用ros :: start(),在这种情况下,你应该在程序退出之前调用ros :: shutdown()。
2.Shutting Down
2.1关闭节点
在任何时候你都可以调用ros :: shutdown()函数关闭你的节点。这将终止所有打开的订阅,发布,服务调用和服务服务器。
默认情况下,roscpp还会安装一个SIGINT处理程序,它会检测Ctrl-C并自动关闭。
2.2测试关机
有两种方法可以检查各种关机状态。最常见的是ros :: ok()。一旦ros :: ok()返回false,节点就完成关闭。ros :: ok()的常见用法:
1while(ros :: ok())
2{
3 ...
4}
另一种检查关闭的方法是ros :: isShuttingDown()方法。只要ros :: shutdown()被调用,该方法就会变为true ,而不是在完成时。通常不鼓励使用ros ::isShuttingDown(),但可以在高级情况下使用。例如,要测试长时间服务回调的内部是否请求关闭节点,因此应该立即退出回调,则需要使用ros ::isShuttingDown()。ros :: ok()在这里不起作用,因为只要回调正在运行,节点就不能完成它的关闭。
2.2.1自定义SIGINT处理程序
你可以安装一个自定义的SIGINT处理程序,它可以很好地处理ROS,如下所示
1#包括<ROS / ros.h>
2#包括<signal.h中>
4void mySigintHandler(int sig)
5{
6 //做一些自定义操作。
7 //例如,向其他节点发布停止消息。
9 //所有默认的sigint处理程序都会调用shutdown()
10 ros :: shutdown();
11}
13int main(int argc,char ** argv)
14{
15 ros :: init(argc,argv,“ my_node_name ”,ros :: init_options :: NoSigintHandler);
16 ros :: NodeHandle nh ;
18 //覆盖默认的ros sigint处理程序。
19 //必须在第一个NodeHandle创建后设置。
20 信号(SIGINT,mySigintHandler);
22 // ...
23 ros :: spin();
24 返回0 ;
25}