說明
介紹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;}