initial commit
This commit is contained in:
157
ov_eval/python/pid_ros.py
Executable file
157
ov_eval/python/pid_ros.py
Executable file
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# OpenVINS: An Open Platform for Visual-Inertial Research
|
||||
# Copyright (C) 2019 Patrick Geneva
|
||||
# Copyright (C) 2019 OpenVINS Contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import os
|
||||
import rosnode
|
||||
import rospy
|
||||
import sys
|
||||
import time
|
||||
|
||||
try:
|
||||
from xmlrpc.client import ServerProxy
|
||||
except ImportError:
|
||||
from xmlrpclib import ServerProxy
|
||||
import psutil
|
||||
|
||||
|
||||
def get_process_ros(node_name, doprint=False):
|
||||
# get the node object from ros
|
||||
node_api = rosnode.get_api_uri(rospy.get_master(), node_name, skip_cache=True)[2]
|
||||
if not node_api:
|
||||
rospy.logwarn("could not get api of node %s (%s)" % (node_name, node_api))
|
||||
return False
|
||||
# now try to get the Pid of this process
|
||||
try:
|
||||
response = ServerProxy(node_api).getPid('/NODEINFO')
|
||||
except:
|
||||
rospy.logwarn("failed to get of the pid of ros node %s (%s)" % (node_name, node_api))
|
||||
return False
|
||||
# try to get the process using psutil
|
||||
try:
|
||||
process = psutil.Process(response[2])
|
||||
if doprint:
|
||||
rospy.loginfo("adding new node monitor %s (pid %d)" % (node_name, process.pid))
|
||||
return process
|
||||
except:
|
||||
rospy.logwarn("unable to open psutil object for %s" % (response[2]))
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# initialize this ros node
|
||||
rospy.init_node("pid_ros")
|
||||
|
||||
# check if we have our params
|
||||
if not rospy.has_param('~nodes') or not rospy.has_param('~output'):
|
||||
rospy.logerr("please specify the nodes and output file for this logger 1")
|
||||
rospy.logerr("rosrun ov_eval pid_ros.py _nodes:=<comma,separated,node,names> _output:=<file.txt>")
|
||||
sys.exit(-1)
|
||||
|
||||
# get our paramters
|
||||
node_csv = rospy.get_param("~nodes")
|
||||
node_list = node_csv.split(',')
|
||||
save_path = rospy.get_param("~output")
|
||||
|
||||
# debug print to console
|
||||
rospy.loginfo("processes: %s (%d in total)" % (node_csv, len(node_list)))
|
||||
rospy.loginfo("save path: %s" % save_path)
|
||||
|
||||
# ===================================================================
|
||||
# ===================================================================
|
||||
|
||||
# make sure the directory is made
|
||||
if not os.path.exists(os.path.dirname(save_path)):
|
||||
try:
|
||||
os.makedirs(os.path.dirname(save_path))
|
||||
except:
|
||||
rospy.logerr("unable to create the save path!!!!!")
|
||||
sys.exit(-1)
|
||||
|
||||
# open the file we will write the stats into
|
||||
file = open(save_path, "w")
|
||||
|
||||
# write header to file
|
||||
header = "# timestamp(s) summed_cpu_perc summed_mem_perc summed_threads"
|
||||
for node in node_list:
|
||||
get_process_ros(node, True) # nice debug print!
|
||||
header += " " + str(node) + "_cpu_perc " + str(node) + "_mem_perc " + str(node) + "_threads"
|
||||
header += "\n"
|
||||
file.write(header)
|
||||
|
||||
# ===================================================================
|
||||
# ===================================================================
|
||||
|
||||
# exit if we should end
|
||||
if rospy.is_shutdown():
|
||||
file.close()
|
||||
sys.exit(-1)
|
||||
|
||||
# now lets loop and get the stats for these processes
|
||||
rate = rospy.Rate(1)
|
||||
while not rospy.is_shutdown():
|
||||
|
||||
# get the pid processes for this object
|
||||
ps_list = []
|
||||
for node in node_list:
|
||||
ps_list.append(get_process_ros(node, False))
|
||||
try:
|
||||
perc_cpu = ps_list[len(ps_list) - 1].cpu_percent(interval=None)
|
||||
perc_mem = ps_list[len(ps_list) - 1].memory_percent()
|
||||
threads = ps_list[len(ps_list) - 1].num_threads()
|
||||
except:
|
||||
continue
|
||||
|
||||
# wait one second so we can collect data
|
||||
rate.sleep()
|
||||
|
||||
# loop through and get our measurement readings
|
||||
perc_cpu = []
|
||||
perc_mem = []
|
||||
threads = []
|
||||
for i in range(0, len(node_list)):
|
||||
try:
|
||||
# get readings
|
||||
p_cpu = ps_list[i].cpu_percent(interval=None)
|
||||
p_mem = ps_list[i].memory_percent()
|
||||
p_threads = ps_list[i].num_threads()
|
||||
# append to our list
|
||||
perc_cpu.append(p_cpu)
|
||||
perc_mem.append(p_mem)
|
||||
threads.append(p_threads)
|
||||
except:
|
||||
# record just zeros if we do not have this value
|
||||
perc_cpu.append(0)
|
||||
perc_mem.append(0)
|
||||
threads.append(0)
|
||||
|
||||
# print what the total summed value is
|
||||
rospy.loginfo("cpu%% = %.3f | mem%% = %.3f | threads = %d" % (sum(perc_cpu), sum(perc_mem), sum(threads)))
|
||||
|
||||
# save the current stats to file!
|
||||
data = "%.8f %.3f %.3f %d" % (time.time(), sum(perc_cpu), sum(perc_mem), sum(threads))
|
||||
for i in range(0, len(node_list)):
|
||||
data += " %.3f %.3f %d" % (perc_cpu[i], perc_mem[i], threads[i])
|
||||
data += "\n"
|
||||
file.write(data)
|
||||
file.flush()
|
||||
|
||||
# finally close the file!
|
||||
file.close()
|
||||
105
ov_eval/python/pid_sys.py
Executable file
105
ov_eval/python/pid_sys.py
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# OpenVINS: An Open Platform for Visual-Inertial Research
|
||||
# Copyright (C) 2019 Patrick Geneva
|
||||
# Copyright (C) 2019 OpenVINS Contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import os
|
||||
import psutil
|
||||
import rospy
|
||||
import sys
|
||||
|
||||
|
||||
def get_process_name(process_name, doprint=False):
|
||||
# try to get the process using psutil
|
||||
# https://stackoverflow.com/a/2241047/7718197
|
||||
processes = []
|
||||
for proc in psutil.process_iter():
|
||||
name, exe, cmdline = "", "", []
|
||||
try:
|
||||
name = proc.name()
|
||||
cmdline = proc.cmdline()
|
||||
exe = proc.exe()
|
||||
except (psutil.AccessDenied, psutil.ZombieProcess):
|
||||
pass
|
||||
except psutil.NoSuchProcess:
|
||||
continue
|
||||
if name == process_name or cmdline[0] == process_name or os.path.basename(exe) == process_name:
|
||||
if doprint:
|
||||
rospy.loginfo("adding new node monitor (pid %d)" % (proc.pid))
|
||||
processes.append(proc)
|
||||
# if we have a process, then success
|
||||
if len(processes) > 0:
|
||||
return processes
|
||||
# else we have failed!
|
||||
rospy.logerr("unable to find process for %s" % (process_name))
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# initialize this ros node
|
||||
rospy.init_node("pid_sys")
|
||||
|
||||
# check if we have our params
|
||||
if len(sys.argv) < 2:
|
||||
rospy.logerr("please specify process name")
|
||||
rospy.logerr("python pid_sys.py <command-name>")
|
||||
sys.exit(-1)
|
||||
|
||||
# load our process, keep trying until we connect to it
|
||||
processes = False
|
||||
rate = rospy.Rate(2)
|
||||
while processes == False and not rospy.is_shutdown():
|
||||
processes = get_process_name(sys.argv[1], True)
|
||||
|
||||
# exit if we should end
|
||||
if rospy.is_shutdown():
|
||||
sys.exit(-1)
|
||||
|
||||
# now lets loop and get the stats for these processes
|
||||
while not rospy.is_shutdown():
|
||||
|
||||
# summed over all the pid for this process
|
||||
sum_perc_cpu = 0.0
|
||||
sum_perc_mem = 0.0
|
||||
sum_threads = 0
|
||||
for p in processes:
|
||||
try:
|
||||
perc_cpu = p.cpu_percent(interval=None)
|
||||
perc_mem = p.memory_percent()
|
||||
threads = p.num_threads()
|
||||
except:
|
||||
continue
|
||||
sum_perc_cpu += perc_cpu
|
||||
sum_perc_mem += perc_mem
|
||||
sum_threads += threads
|
||||
|
||||
# print what the total summed value is
|
||||
print("cpu percent = %.3f" % sum_perc_cpu)
|
||||
print("mem percent = %.3f" % sum_perc_mem)
|
||||
print("num threads = %d" % sum_threads)
|
||||
processes = False
|
||||
|
||||
# try to get the process again, this allows us to handle
|
||||
# the spawning of new threads or removing of threads that have finished
|
||||
while processes == False and not rospy.is_shutdown():
|
||||
processes = get_process_name(sys.argv[1])
|
||||
if not processes == False:
|
||||
for p in processes:
|
||||
p.cpu_percent(interval=None)
|
||||
rate.sleep()
|
||||
Reference in New Issue
Block a user