【ROS】在程序中判断 roscore 是否正常运行 | 强制结束 rosmater 进程

ros::ok()ros::shutdown()经常一起使用,以确保节点能够在接收到关闭信号或调用ros::shutdown()后安全退出。例如:

C++ 版本

int main(int argc, char **argv) {
    ros::init(argc, argv, "example_node");
    ros::NodeHandle nh;

    while (ros::ok()) {
        // 执行主要逻辑
        if (some_condition) {
            ros::shutdown(); // 满足条件时主动关闭节点
        }
        ros::spinOnce();
    }

    ROS_INFO("Node has been shut down.");
    return 0;
}

Python 版本

import rospy

def main():
    rospy.init_node('example_node')
    rate = rospy.Rate(10)  # 10Hz

    while not rospy.is_shutdown():
        # 节点的主循环
        rospy.loginfo("Node is running...")

        # 假设有一个条件需要主动关闭节点
        if some_condition:
            rospy.logwarn("Condition met, shutting down node.")
            rospy.signal_shutdown("Condition met for shutdown.")

        rate.sleep()  # 控制循环频率

    rospy.loginfo("Node has been shut down.")

if __name__ == '__main__':
    try:
        main()
    except rospy.ROSInterruptException:
        pass

另外一种情况是,我们在启动节点前,又或者在一个普通进程(非 ROS 节点)中,想要知道 roscore 有没有正常运行(不光是 rosmaster 进程在运行,提供的节点注册与参数查询等服务也应该能够正常使用)。

一种方法,通过终端命令

pgrep -f rosmaster

实际上,该方法并不靠谱,只能保证进程存在,但是无法得知功能是否正常。

如果通过 rosnode list/rostopic list 的返回值也可以判断 rosmaster 的运行状态,而且比较靠谱。但是不能调用过于频繁。

$ rosnode list
/rosout

$ rosnode list
ERROR: Unable to communicate with master!

也可以使用 rosnode ping 命令来检查 roscore 是否在运行,因为如果 roscore 正常启动,rosnode ping 将能够成功与主节点通信。

下面是一个单次执行 rosnode ping 的命令示例,通过它来判断 roscore 是否运行:

rosnode ping /rosout -c 1
  • /rosoutroscore 启动时自动创建的日志记录节点。只要 roscore 正常运行,/rosout 节点就会存在。
  • c 1 参数表示只执行一次 ping 操作。

实现代码如下

import subprocess
import time

def is_roscore_running():
    try:
        # 执行 `rosnode ping /rosout -c 1` 命令
        result = subprocess.run(['rosnode', 'ping', '/rosout', '-c', '1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        
        # 检查返回值和输出
        if result.returncode == 0:
            print("roscore is running.")
            return True
        else:
            print("roscore is not running.")
            return False
    except Exception as e:
        print(f"Error occurred: {e}")
        return False

# 循环检查,每隔1秒
while True:
    is_roscore_running()
    time.sleep(1)

如果 roscore 进程以异常方式退出,很可能保留 rosmaster 在后台运行,但是功能异常,有没有终端可以进行操作,此时可以强制结束。

pkill -9 roscore && pkill -9 rosmaster
上一篇
下一篇