C++初始化和關閉roscpp節點

說明

介紹roscpp節點的初始化和關閉

初始化

需要兩步來初始化節點:

初始化節點:調用ros::init()函數來初始化節點,提供命令行參數給ROS,允許命名節點並提供不同的可選參數。

開始節點:調用ros::NodeHandle來啓用節點

初始化節點

查閱 ros::init() API

在調用roscpp其他函數之前,必需先調用ros::init()。

兩個常用的用法:

ros::init(argc, argv, “my_node_name”);

或者

ros::init(argc, argv, “my_node_name”, ros::init_options::AnonymousName);

一般情況下,符合如下形式:

void ros::init(, std::string ode_name, uint32_t options);

函數分析:

argc 和 argv,參數列表,ROS使用這些來解析來自命令行的映射參數

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::master::check()或其他函數來檢查主機狀態。

初始化選項

查閱ros::init_options code API

ros::init_options::NoSigintHandler

不要安裝SIGINT處理器。在這種情況下,你應該安裝自己SIGINT處理器,確保節點得到正確關閉時退出。

注意,SIGINT的默認動作是終止進程,所以如果你想做你自己的SIGTERM處理,你也要使用這個選項。

ros::init_options::AnonymousName

匿名節點名稱。將隨機數添加到節點名稱的結尾,使其成爲唯一的。

ros::init_options::NoRosout

不要廣播rosconsole輸出到/rosout話題。

訪問命令行參數

正如上面提到的,調用ros::init()帶有argc和argv參數,將從命令行清除ROS的參數。

如果你需要解析命令行之前調用ros::init(),你可以調用(新的ROS 0.10)ros::removeROSArgs()函數。

開始節點

最常用的方法開始節點:

ros::NodeHandle nh;

當第一個ros::NodeHandle創建時候,會調用ros::start()

最後一個ros::NodeHandle銷燬時,會調用 ros::shutdown()

如果想自己管理節點的生命期,需要開始時調用ros::start(),在關閉程序前調用ros::shutdown()。

關閉節點

你可以在任何時間調用ros::shutdown()功能關閉節點。

將關閉所有打開的訂閱、發佈、服務調用和服務服務器。

測試關閉

有兩種方法檢查關閉狀態

最常用的方法是ros::ok(),如:

while (ros::ok()){ …}

一旦ros::ok() 返回false,節點就已經關閉。

另外一種方法: ros::isShuttingDown(),當ros::shutdown() 調用,就會返回true。

一般不鼓勵使用,不過在一些高級用法中還是有用的。

例如在持續運行的服務節點的回調函數,當節點請求關閉的時候,回調函數應該立即關閉。這時候ros::isShuttingDown()就要用到,而 ros::ok() 就不能工作,因爲主要回調函數在運行中,節點就不能關閉。

自定義信號處理器

你可以安裝一個自定義的信號處理器,能跟ROS完美結合:

示例代碼:

#include <ros/ros.h>
include <signal.h>
void mySigintHandler(int sig)
{
// Do some custom action.
// For example, publish a stop message to some other nodes.
// All the default sigint handler does is call shutdown()
ros::shutdown();
}
int main(int argc, char** argv)
{
ros::init(argc, argv, “my_node_name”, ros::init_options::NoSigintHandler);
ros::NodeHandle nh;
signal(SIGINT, mySigintHandler);
ros::spin();
return 0;}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章