通过 kill 优雅地杀死 rosbag

Kill rosbag gracefully via kill

我想通过终端优雅地杀死一个 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 的预期方式启动和关闭已完成的节点,以便 API 可以跟踪。 为了优雅地结束节点,我们假设启动了一个名称为 my_bag 的 rosbag 节点:

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

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

rosnode kill /my_bag

Link for reference

如@Tik0 的回答中的参考所述,您可以在 bash 中添加陷阱以捕获 SIGINT (Ctrl+C) 并从那里调用 rosnode kill,例如:

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

我想从

的启动文件中开始 rosbag 记录
<node pkg="rosbag" type="record" name="rosbag_recorder" args="record --all --exclude '/unwanted/(.*)'"/>

并在使用 CTRL+C.

停止 roslaunch 时出现 .active 文件问题

一个适合我的解决方案是在启动文件中启动以下节点,它会根据用户请求通过键入 "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)

启动 rosbag 节点时给一个特殊的名字,因为它很容易关闭,而且如果你想给 bagfile name 一个特殊的名字;

-a表示保存所有主题,你可以给主题名

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

现在如果你 运行 rosnode list 和相对文件夹中的 bagFileName.bag.active 文件,你可以看到名为 'bagNodeName' 的 运行ning 节点

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

rosnode kill bagNodeName

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