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