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 import roslib
00032 roslib.load_manifest('rqt_py_common')
00033 import roslib.msgs
00034 from rostopic import get_topic_type
00035 from python_qt_binding.QtCore import qDebug
00036
00037
00038 def get_field_type(topic_name):
00039 """
00040 Get the Python type of a specific field in the given registered topic.
00041 If the field is an array, the type of the array's values are returned and the is_array flag is set to True.
00042 This is a static type check, so it works for unpublished topics and with empty arrays.
00043
00044 :param topic_name: name of field of a registered topic, ``str``, i.e. '/rosout/file'
00045 :returns: field_type, is_array
00046 """
00047
00048 topic_type, real_topic_name, _ = get_topic_type(topic_name)
00049 if topic_type is None:
00050
00051 return None, False
00052
00053 message_class = roslib.message.get_message_class(topic_type)
00054 if message_class is None:
00055 qDebug('topic_helpers.get_field_type(%s): get_message_class(%s) failed' % (topic_name, topic_type))
00056 return None, False
00057
00058 slot_path = topic_name[len(real_topic_name):]
00059 return get_slot_type(message_class, slot_path)
00060
00061
00062 def get_slot_type(message_class, slot_path):
00063 """
00064 Get the Python type of a specific slot in the given message class.
00065 If the field is an array, the type of the array's values are returned and the is_array flag is set to True.
00066 This is a static type check, so it works for unpublished topics and with empty arrays.
00067
00068 :param message_class: message class type, ``type``, usually inherits from genpy.message.Message
00069 :param slot_path: path to the slot inside the message class, ``str``, i.e. 'header/seq'
00070 :returns: field_type, is_array
00071 """
00072 is_array = False
00073 fields = [f for f in slot_path.split('/') if f]
00074 for field_name in fields:
00075 try:
00076 field_name, _, field_index = roslib.msgs.parse_type(field_name)
00077 except roslib.msgs.MsgSpecException:
00078 return None, False
00079 if field_name not in getattr(message_class, '__slots__', []):
00080
00081 return None, False
00082 slot_type = message_class._slot_types[message_class.__slots__.index(field_name)]
00083 slot_type, slot_is_array, _ = roslib.msgs.parse_type(slot_type)
00084 is_array = slot_is_array and field_index is None
00085 if roslib.msgs.is_valid_constant_type(slot_type):
00086 if slot_type == 'string':
00087 message_class = str
00088 elif slot_type == 'bool':
00089 message_class = bool
00090 else:
00091 message_class = type(roslib.msgs._convert_val(slot_type, 0))
00092 else:
00093 message_class = roslib.message.get_message_class(slot_type)
00094 return message_class, is_array
00095
00096
00097 def is_slot_numeric(topic_name):
00098 """
00099 Check is a slot in the given topic is numeric, or an array of numeric values.
00100 This is a static type check, so it works for unpublished topics and with empty arrays.
00101
00102 :param topic_name: name of field of a registered topic, ``str``, i.e. '/rosout/file'
00103 :returns: is_numeric, is_array, description
00104 """
00105 field_type, is_array = get_field_type(topic_name)
00106 if field_type in (int, float):
00107 if is_array:
00108 message = 'topic "%s" is numeric array: %s[]' % (topic_name, field_type)
00109 else:
00110 message = 'topic "%s" is numeric: %s' % (topic_name, field_type)
00111 return True, is_array, message
00112
00113 return False, is_array, 'topic "%s" is NOT numeric: %s' % (topic_name, field_type)