1. 程式人生 > >(7)初始化和關閉roscpp節點

(7)初始化和關閉roscpp節點

參考連結: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的行為。所以多個選項可以指定。選項在初始化選項部分中描述。
  • 其他形式的 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);