Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import os
00036 import copy
00037
00038 import roslib;roslib.load_manifest('rqt_robot_monitor')
00039 import rospy
00040 from diagnostic_msgs.msg import DiagnosticStatus
00041 from python_qt_binding.QtGui import QColor, QIcon
00042
00043 class Util(object):
00044 """
00045
00046 @todo: Utils and common configs are mixed in this class.
00047 """
00048
00049 _SECONDS_TIMELINE = 30
00050
00051
00052 _ERR_ICON = QIcon.fromTheme('dialog-error')
00053 _WARN_ICON = QIcon.fromTheme('dialog-warning')
00054 _OK_ICON = QIcon.fromTheme('emblem-default')
00055
00056 _STALE_ICON = QIcon.fromTheme('dialog-question')
00057
00058 _IMG_DICT = {0: _OK_ICON, 1: _WARN_ICON, 2: _ERR_ICON, 3: _STALE_ICON}
00059
00060 _COLOR_DICT = {0: QColor(85, 178, 76),
00061 1: QColor(222, 213, 17),
00062 2: QColor(178, 23, 46),
00063 3: QColor(40, 23, 176)
00064 }
00065
00066
00067
00068
00069 DiagnosticStatus.STALE = 3
00070
00071 _DICTKEY_TIMES_ERROR = 'times_errors'
00072 _DICTKEY_TIMES_WARN = 'times_warnings'
00073 _DICTKEY_INDEX = 'index'
00074 _DICTKEY_STATITEM = 'statitem'
00075
00076
00077 def __init__(self):
00078 super(Util, self).__init__()
00079
00080 @staticmethod
00081 def _update_status_images(diagnostic_status, statusitem):
00082 """
00083 Taken from robot_monitor.robot_monitor_panel.py.
00084
00085 @param status: DiagnosticStatus
00086 @param node: StatusItem
00087 @author: Isaac Saito
00088 """
00089
00090 name = diagnostic_status.name
00091 if (name is not None):
00092
00093 level = diagnostic_status.level
00094 rospy.logdebug('New diagnostic_status level: %s. Last lv: %s name: %s',
00095 level, statusitem.last_level, name)
00096 if (diagnostic_status.level != statusitem.last_level):
00097
00098 statusitem.setIcon(0, Util._IMG_DICT[level])
00099 statusitem.last_level = level
00100 return
00101
00102 '''
00103 @param param: status_name is a string that may consists of status names that
00104 are delimited by slash.
00105 @return: string
00106 '''
00107 @staticmethod
00108 def get_nice_name(status_name):
00109 name = status_name.split('/')[-1]
00110 rospy.logdebug(' get_nice_name name = %s', name)
00111 return name
00112
00113 @staticmethod
00114 def remove_parent_name(status_name):
00115 return ('/'.join(status_name.split('/')[2:])).strip()
00116
00117 @staticmethod
00118 def get_parent_name(status_name):
00119 return ('/'.join(status_name.split('/')[:-1])).strip()
00120
00121 @staticmethod
00122 def gen_headline_status_green(diagnostic_status):
00123
00124
00125 return "%s" % Util.get_nice_name(diagnostic_status.name)
00126
00127 @staticmethod
00128 def gen_headline_warn_or_err(diagnostic_status):
00129 return "%s : %s" % (Util.get_nice_name(diagnostic_status.name),
00130 diagnostic_status.message)
00131
00132 @staticmethod
00133 def _get_color_for_message(msg, mode = 0):
00134 """
00135
00136 @param msg: Either DiagnosticArray or DiagnosticsStatus.
00137 @param mode: int. When 0, this func will iterate msg to find
00138 DiagnosticsStatus.level and put it into a dict.
00139 When 1, this func finds DiagnosticsStatus.level from msg
00140 without iteration (thus, msg is expected to be
00141 DiagnosticsStatus instance).
00142
00143 Copied from robot_monitor.
00144 """
00145
00146 level = 0
00147 min_level = 255
00148
00149 lookup = {}
00150 for status in msg.status:
00151 lookup[status.name] = status
00152
00153 names = [status.name for status in msg.status]
00154 names = [name for name in names if len(Util.get_parent_name(name)) == 0]
00155 for name in names:
00156 status = lookup[name]
00157 if (status.level > level):
00158 level = status.level
00159 if (status.level < min_level):
00160 min_level = status.level
00161
00162
00163 if (level > 2 and min_level <= 2):
00164 level = 2
00165
00166
00167 rospy.logdebug(' get_color_for_message color lv=%d', level)
00168 return Util._COLOR_DICT[level]
00169
00170 @staticmethod
00171 def get_correspondent(key, list_statitem):
00172 """
00173
00174 @param key: String.
00175 @param list_statitem: DiagnosticsStatus
00176 @return: StatusItem
00177 """
00178 names_from_list = [Util.get_nice_name(k.name) for k in list_statitem]
00179 key_niced = Util.get_nice_name(key)
00180 index_key = -1
00181 statitem_key = None
00182 if key_niced in names_from_list:
00183 index_key = names_from_list.index(key_niced)
00184 statitem_key = list_statitem[index_key]
00185 rospy.logdebug(' get_correspondent index_key=%s statitem_key=%s',
00186 index_key, statitem_key)
00187 return {Util._DICTKEY_INDEX : index_key,
00188 Util._DICTKEY_STATITEM : statitem_key}
00189
00190 @staticmethod
00191 def get_correspondent_index(key, statusitems):
00192 """
00193 @deprecated: Use get_correspondent
00194
00195 @param key: string
00196 @param statusitems: DiagnosticStatus[]
00197 @return: int of index that key is found in array. -1 if not found
00198 """
00199
00200 names = [Util.get_nice_name(k.name) for k in statusitems]
00201
00202 rospy.logdebug('\tget_correspondent_index len of names=%d statusitems=%d',
00203 len(names), len(statusitems))
00204
00205 if key in names:
00206 rospy.logdebug(' get_correspondent_index key IS contained.')
00207 return names.index(key)
00208 else:
00209 rospy.logdebug('** get_correspondent_index key IS NOT contained.')
00210 return -1
00211
00212 @staticmethod
00213 def get_children(name, diag_array):
00214 """
00215
00216 @param msg: DiagnosticArray
00217 @return: DiagnosticStatus[]
00218 """
00219
00220 ret = []
00221 for k in diag_array.status:
00222 if k.name.startswith(name):
00223
00224 if not k.name == name:
00225
00226 ret.append(k)
00227 return ret