【问题标题】:Kill rosbag gracefully via kill通过 kill 优雅地杀死 rosbag
【发布时间】:2018-06-02 02:02:27
【问题描述】:

我想通过终端优雅地杀死 rosbag 实例。 优雅地意味着在这种情况下,rosbag 文件在 kill 之后没有后缀 .active

所以我从终端执行以下操作,将推荐的SIGINT 发送到 rosbag:

$ rosbag record /some/topic &
$ RPID=$!
$ # do some stuff 
$ kill -2 $RPID

不幸的是,该包仍然处于活动状态,并且可能并非所有内容都存储到磁盘中。 但是,如果我将 rosbag 放入启动文件中,它似乎可以工作:

$ roslaunch rosbag_record.launch &
$ LPID=$!
$ # do some stuff 
$ kill -2 $LPID

现在 rosbag 保持完整,并且在没有 active 后缀的情况下被存储。

现在有趣的问题是,在第一种情况下我做错了什么。 我虽然杀死一个启动文件,在这种情况下杀死 roscore,会引发一个ros::shutdown(),这会在所有进程中导致一个SIGINT。 但是使用kill 的手动方式似乎有不同的行为。

【问题讨论】:

  • 此问题在ROS Answers 上有多个重复项。您可以在脚本中使用rosnode killtake care of killing child processes
  • 哦,太好了!您会建议关闭我的问题,还是应该将其留作参考?
  • 我认为保留作为参考可能很有用,因为似乎有很多人不知道 ROS Answers。您可以自己写一个简短的答案,最后通过相关 ROS Answers 问题的链接解释您是如何修复它的。

标签: terminal kill ros


【解决方案1】:

本机信号处理没有得到很好的支持,最好使用 ROS 的预期方式来启动和关闭已完成的节点,以便 API 可以跟踪。 为了优雅地结束一个节点,我们假设一个名为 my_bag 的 rosbag 节点已经启动:

rosbag record -o /file/name /topic __name:=my_bag

然后,使用rosnode kill 命令和节点名称优雅地杀死节点:

rosnode kill /my_bag

Link for reference

【讨论】:

    【解决方案2】:

    正如@Tik0's answer中的参考资料所述,您可以在 bash 中添加一个陷阱来捕获 SIGINT (Ctrl+C) 并从那里调用rosnode kill,例如:

    #!/bin/bash
    trap "rosnode kill /bagger" SIGINT
    rosbag record /my_topic __name:=bagger &
    roslaunch mypackage launch.launch
    

    【讨论】:

      【解决方案3】:

      我想从一个启动文件中开始 rosbag 记录

      <node pkg="rosbag" type="record" name="rosbag_recorder" args="record --all --exclude '/unwanted/(.*)'"/>
      

      并且在使用 CTRL+C 停止 roslaunch 时遇到.active-files 问题。

      一个适合我的解决方案是在启动文件中启动以下节点,它会根据用户请求通过键入 "stop" 触发 rosnode kill

      #!/usr/bin/env python
      import rospy
      import subprocess
      
      NODENAME = 'keypress_killer'
      TAG = NODENAME + ": "
      
      if __name__ == '__main__':
          rospy.init_node(NODENAME)
          while not rospy.is_shutdown():
              try:
                  rospy.logwarn(TAG + "Plase type quoted \"stop\" to gracefully kill all nodes and the rosbag recording")
                  input_str = input()
                  if input_str == "stop":
                      rospy.logwarn(TAG + "Stopping all nodes and rosbag recording...")
                      subprocess.check_call(['rosnode', 'kill', '-a'])  # gracefully kill the rosbag recorder
                  else:
                      raise ValueError
              except:
                  rospy.logerr(TAG + "Unknown command, please type quoted \"stop\" to gracefully kill all nodes and the rosbag recording")
                  rospy.sleep(0.1)
      
      

      【讨论】:

        【解决方案4】:

        以特殊名称启动 rosbag 节点,因为这样可以轻松关闭,并且如果您想为 bagfile 名称提供特殊名称;

        -a 表示保存所有主题,如果需要,可以给主题名称

        rosbag record --output-name=bagFileName -a __name:=bagNodeName
        

        现在,如果您运行 rosnode list 以及相关文件夹中的 bagFileName.bag.active 文件,您可以看到名为“bagNodeName”的正在运行的节点

        然后用于关闭节点并自动保存包文件;

        rosnode kill bagNodeName
        

        现在您应该看到 bagFileName.bag 文件

        【讨论】:

          猜你喜欢
          • 2017-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-19
          • 2020-07-28
          • 1970-01-01
          • 2014-11-19
          • 1970-01-01
          相关资源
          最近更新 更多