< >
Home » ROS与C++入门教程 » ROS与C++入门教程-初始化和关闭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);
  
  //...
  ros::spin();
  return 0;
}

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ROS与C++入门教程