(7)初始化和關閉roscpp節點
阿新 • • 發佈:2018-12-14
參考連結:ROS與C++入門教程-初始化和關閉roscpp節點
ROS與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(<command line or remapping arguments>, std::string node_name, uint32_t options);
-
函式分析:
- argc 和 argv,引數列表,ROS使用這些來解析來自命令列的
- node_name,節點名,在ROS系統裡必需是唯一的。如果有同名的節點啟動,就會先自動關閉前面的,如果想啟動多個相同節點,使用init_options::AnonymousName引數。
- options,這是一個可選的引數,可以指定某些選項,改變roscpp的行為。所以多個選項可以指定。選項在初始化選項部分中描述。
- argc 和 argv,引數列表,ROS使用這些來解析來自命令列的
-
其他形式的 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;
// Override the default ros sigint handler.
// This must be set after the first NodeHandle is created.
signal(SIGINT, mySigintHandler);