基于Python+Ros通讯机制实时监控各小车硬件信息

Ros实时监控各小车硬件信息

在小车移动过程中如何实现对小车硬件信息的硬件信息,首先我们能想到的是通过使用Prometheus(普罗米修斯)对小车硬件信息进行监控与展示,但这里我们想通过编写python脚本实现同样的功能。

定义小车硬件信息服务

简单的自定义一个硬件信息服务类型InformationSystem.srv

bool state
---
string information

小车硬件信息服务端,当有client客服端发送请求时,服务端通过python的psutil库对小车硬件信息进行获取,转化为json格式字符串反馈给客户端

#!/usr/bin/env python
import psutil
import rospy
from information_system.srv import InformationSystem
import json
class Information_server:
    def __init__(self,robot_name="robot1"):
        self.robot_name=robot_name
    def InformationCallback(self,req):
        try:
            if req.state:
                memory = psutil.virtual_memory()
                cpu_percent = psutil.cpu_percent()
                return json.dumps({"memory":{"total":memory.total,"available":memory.available,"percent":memory.percent,"used":memory.used,"free":memory.free},"cpu":{"percent":cpu_percent}}).replace(" ","")
            else:
                return None
        except:
            return None
    def server(self):
        s = rospy.Service(str(self.robot_name)+"/information", InformationSystem, self.InformationCallback)
        rospy.spin()
       
if __name__=="__main__":
    rospy.init_node("information")
    robot_name = rospy.get_param('~robot_name','robot1')
    information_server = Information_server(robot_name=robot_name)
    information_server.server()

客户端各小车硬件信息获取汇总并可视化

import rospy
import math
import  numpy as np 
import matplotlib.pyplot as plt
import time
import psutil
from information_system.srv import InformationSystem
import json
import threading

# 创建一个客户端类用于获取各小车硬件信息
class Get_Information:
    def __init__(self, robot_name):
        self.robot_name = robot_name
    def information_client(self):
        rospy.wait_for_service(str(self.robot_name)+"/information")
        try:
            information_client = rospy.ServiceProxy(self.robot_name+"/information", InformationSystem)
            response = information_client(True)
            return response.information
        except:
            return None
            
# 画图的类用于cpu信息展示
class Cpu_Figure:
    def __init__(self,robot_names=[],x_len=10,colors=["r","g","b"]):
        self.robot_names = robot_names
        self.x_len = x_len
        self.x_index = np.array(range(1,x_len+1))
        self.x_label = np.zeros(x_len)
        self.data_init()
        self.colors = colors
        
    # 初始化数据,构建一个用于存放数据的字典
    def data_init(self):
        self.data_dict = {}
        for robot_name in self.robot_names:
            self.data_dict[robot_name] = np.zeros(self.x_len)
            
	# 通过客户端类,json获取数据
    def get_data(self,robot_name):         
        information = Get_Information(robot_name).information_client()
        if information != None:
            information = json.loads(information)
            new_data = float(information["cpu"]["percent"])
            self.data_dict[robot_name] = np.append(np.delete(self.data_dict[robot_name],0),new_data)
            print("new_data: ",self.data_dict[robot_name])
            
    # 多线程获取更好的实现时间轴上的同步可取消注释替换下面的update_data()
    #def update_data(self):
     #   threads = [threading.Thread(target=self.get_data,args=(robot_name,)) for robot_name in self.robot_names]
      #  for t in threads:
       #     t.setDaemon(True)
        #    t.start()
        #for t in threads:
         #   t.join()
         
    # 简单的循环更新没有较好的实时性
    def update_data(self):
        for robot_name in self.robot_names:
            self.get_data(robot_name)
            
	# 时间轴标签更新
    def update_label(self):
        self.x_label = np.append(np.delete(self.x_label,0),time.strftime("%H:%M:%S", time.localtime()))
        
	# 绘图的方法
    def plt_show(self):
    	#
        figID = 1
        fig = plt.figure(num=figID, figsize=(10,5))
        ax = fig.add_subplot(1,1,1)
        #ax1 ,ax2 ,ax3 = [fig.add_subplot(1,len(self.robot_names),i)for i in range(len(self.robot_names))]+[None for i in range(3-len(self.cup_num))]
        while plt.fignum_exists(figID):    # 通过判断创建的窗口是否存在作为循环条件,防止关闭当前窗口后,产生新的窗口导致无法退出程序
            ax.set_xlim([1,10])
            ax.set_ylim([0,100])
            fontdict = {'fontsize': 10}
            ax.set_xlabel('time')
            ax.set_ylabel('use')
            ax.set_title('cup')
            self.update_label()
            start_time = time.time() 
            self.update_data()
            ax.set_xticklabels(self.x_label, fontdict=fontdict)
            for i,robot_name in enumerate(self.robot_names):
                line = ax.plot([0,0],[10,100],self.colors[i],marker='*',label=robot_name)[0]
                line.set_xdata(self.x_index) 
                line.set_ydata(self.data_dict[robot_name])
                for i in range(self.x_len):
                    ax.text(self.x_index[i], self.data_dict[robot_name][i]+0.05, '%.2f'% self.data_dict[robot_name][i]+"%" , ha='center', va= 'bottom',fontsize=7)
            plt.legend(loc=1)
            # 暂停
            plt.pause(0.5)

            if time.time() - start_time <= 20:
                time.sleep(time.time() - start_time)
            ax.cla()


if __name__=="__main__":
    rospy.init_node("information_show")
    fig = Cpu_Figure(robot_names = ["robot2","robot3"])
    fig.plt_show()  

结论

由于每次请求数据到绘图需要一定时间会有十几秒的延迟,待继续优化。目前效果图为两条折线,后续可考虑加入内存等硬件信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值