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
/rosout
是roscore
启动时自动创建的日志记录节点。只要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