33 from __future__
import division
38 from python_qt_binding.QtCore
import Slot, QSignalMapper, QTimer, qWarning
44 from .publisher_widget
import PublisherWidget
51 super(Publisher, self).
__init__(context)
52 self.setObjectName(
'Publisher')
61 if context.serial_number() > 1:
62 self._widget.setWindowTitle(
63 self._widget.windowTitle() + (
' (%d)' % context.serial_number()))
67 for module
in (math, random, time):
68 self._eval_locals.update(module.__dict__)
77 self._timeout_mapper.mapped[int].connect(self.
publish_once)
80 context.add_widget(self.
_widget)
82 @Slot(str, str, float, bool)
85 'topic_name': str(topic_name),
86 'type_name': str(type_name),
88 'enabled': bool(enabled),
95 publisher_info[
'counter'] = 0
96 publisher_info[
'enabled'] = publisher_info.get(
'enabled',
False)
97 publisher_info[
'expressions'] = publisher_info.get(
'expressions', {})
100 publisher_info[
'type_name'])
101 if publisher_info[
'message_instance']
is None:
106 publisher_info[
'publisher'] = rospy.Publisher(
107 publisher_info[
'topic_name'], type(publisher_info[
'message_instance']), queue_size=100)
109 publisher_info[
'publisher'] = rospy.Publisher(
110 publisher_info[
'topic_name'], type(publisher_info[
'message_instance']))
111 publisher_info[
'timer'] = QTimer(self)
114 self.
_publishers[publisher_info[
'publisher_id']] = publisher_info
115 self._timeout_mapper.setMapping(publisher_info[
'timer'], publisher_info[
'publisher_id'])
116 publisher_info[
'timer'].timeout.connect(self._timeout_mapper.map)
117 if publisher_info[
'enabled']
and publisher_info[
'rate'] > 0:
118 publisher_info[
'timer'].start(int(1000.0 / publisher_info[
'rate']))
120 self._widget.publisher_tree_widget.model().
add_publisher(publisher_info)
122 @Slot(int, str, str, str, object)
123 def change_publisher(self, publisher_id, topic_name, column_name, new_value, setter_callback):
124 handler = getattr(self,
'_change_publisher_%s' % column_name,
None)
125 if handler
is not None:
126 new_text = handler(self.
_publishers[publisher_id], topic_name, new_value)
127 if new_text
is not None:
128 setter_callback(new_text)
131 publisher_info[
'enabled'] = (new_value
and new_value.lower()
in [
'1',
'true',
'yes'])
135 if publisher_info[
'enabled']
and publisher_info[
'rate'] > 0:
136 publisher_info[
'timer'].start(int(1000.0 / publisher_info[
'rate']))
138 publisher_info[
'timer'].stop()
142 type_name = new_value
147 slot_path = topic_name[len(publisher_info[
'topic_name']):].strip(
'/').split(
'/')
148 parent_slot = eval(
'.'.join([
"publisher_info['message_instance']"] + slot_path[:-1]))
151 slot_name = slot_path[-1]
152 slot_index = parent_slot.__slots__.index(slot_name)
155 if slot_value
is None:
156 qWarning(
'Publisher._change_publisher_type(): could not find type: %s' % (type_name))
157 return parent_slot._slot_types[slot_index]
161 parent_slot._slot_types[slot_index] = type_name
162 setattr(parent_slot, slot_name, slot_value)
164 self._widget.publisher_tree_widget.model().update_publisher(publisher_info)
168 rate = float(new_value)
170 qWarning(
'Publisher._change_publisher_rate(): could not parse rate value: %s' %
173 publisher_info[
'rate'] = rate
177 publisher_info[
'timer'].stop()
178 if publisher_info[
'enabled']
and publisher_info[
'rate'] > 0:
179 publisher_info[
'timer'].start(int(1000.0 / publisher_info[
'rate']))
181 return '%.2f' % publisher_info[
'rate']
184 expression = str(new_value)
185 if len(expression) == 0:
186 if topic_name
in publisher_info[
'expressions']:
187 del publisher_info[
'expressions'][topic_name]
192 slot_type, is_array = get_field_type(topic_name)
196 error_prefix =
'# error' 197 error_prefix_pos = expression.find(error_prefix)
198 if error_prefix_pos >= 0:
199 expression = expression[:error_prefix_pos]
202 old_expression = publisher_info[
'expressions'].get(topic_name,
None)
203 publisher_info[
'expressions'][topic_name] = expression
207 publisher_info[
'message_instance'], publisher_info[
'topic_name'],
208 publisher_info[
'expressions'], publisher_info[
'counter'])
210 publisher_info[
'message_instance']._check_types()
211 except Exception
as e:
212 print(
'serialization error: %s' % e)
213 if old_expression
is not None:
214 publisher_info[
'expressions'][topic_name] = old_expression
216 del publisher_info[
'expressions'][topic_name]
217 return '%s %s: %s' % (expression, error_prefix, e)
220 return '%s %s evaluating as "%s"' % (expression, error_prefix, slot_type.__name__)
224 if '[' in type_str
and type_str[-1] ==
']':
225 type_str, array_size_str = type_str.split(
'[', 1)
226 array_size_str = array_size_str[:-1]
227 if len(array_size_str) > 0:
228 array_size = int(array_size_str)
232 return type_str, array_size
237 base_message_type = roslib.message.get_message_class(base_type_str)
238 if base_message_type
is None:
239 print(
'Could not create message of type "%s".' % base_type_str)
242 if array_size
is not None:
244 for _
in range(array_size):
245 message.append(base_message_type())
247 message = base_message_type()
251 successful_eval =
True 257 successful_eval =
False 265 value = str(expression)
266 successful_eval =
True 268 elif successful_eval:
269 type_set = set((slot_type, type(value)))
273 if type_set <= set((list, tuple))
or type_set <= set((int, float)):
275 value = slot_type(value)
277 if successful_eval
and isinstance(value, slot_type):
281 'Publisher._evaluate_expression(): failed to evaluate expression: "%s" as ' 282 'Python type "%s"' % (expression, slot_type.__name__))
287 if topic_name
in expressions
and len(expressions[topic_name]) > 0:
290 if hasattr(message,
'_type'):
291 message_type = message._type
293 message_type = type(message)
298 value = message_type()
302 elif hasattr(message,
'__slots__'):
303 for slot_name
in message.__slots__:
305 getattr(message, slot_name), topic_name +
'/' + slot_name, expressions, counter)
306 if value
is not None:
307 setattr(message, slot_name, value)
309 elif type(message)
in (list, tuple)
and (len(message) > 0):
310 for index, slot
in enumerate(message):
312 slot, topic_name +
'[%d]' % index, expressions, counter)
314 if not hasattr(message[0],
'__slots__')
and value
is not None:
315 message[index] = value
321 publisher_info = self._publishers.get(publisher_id,
None)
322 if publisher_info
is not None:
323 publisher_info[
'counter'] += 1
325 publisher_info[
'message_instance'],
326 publisher_info[
'topic_name'],
327 publisher_info[
'expressions'],
328 publisher_info[
'counter'])
329 publisher_info[
'publisher'].publish(publisher_info[
'message_instance'])
333 publisher_info = self._publishers.get(publisher_id,
None)
334 if publisher_info
is not None:
335 publisher_info[
'timer'].stop()
336 publisher_info[
'publisher'].unregister()
340 publisher_copies = []
341 for publisher
in self._publishers.values():
343 publisher_copy.update(publisher)
344 publisher_copy[
'enabled'] =
False 345 del publisher_copy[
'timer']
346 del publisher_copy[
'message_instance']
347 del publisher_copy[
'publisher']
348 publisher_copies.append(publisher_copy)
349 instance_settings.set_value(
'publishers', repr(publisher_copies))
352 publishers = eval(instance_settings.value(
'publishers',
'[]'))
353 for publisher
in publishers:
357 self._widget.publisher_tree_widget.model().clear()
358 for publisher_info
in self._publishers.values():
359 publisher_info[
'timer'].stop()
360 publisher_info[
'publisher'].unregister()
364 self._widget.shutdown_plugin()
def shutdown_plugin(self)
def publish_once(self, publisher_id)
def _create_message_instance(self, type_str)
def _change_publisher_topic(self, publisher_info, topic_name, new_value)
def restore_settings(self, plugin_settings, instance_settings)
def _change_publisher_type(self, publisher_info, topic_name, new_value)
def save_settings(self, plugin_settings, instance_settings)
def __init__(self, context)
def _evaluate_expression(self, expression, slot_type)
def clean_up_publishers(self)
def add_publisher(self, topic_name, type_name, rate, enabled)
def _change_publisher_expression(self, publisher_info, topic_name, new_value)
def change_publisher(self, publisher_id, topic_name, column_name, new_value, setter_callback)
def _change_publisher_rate(self, publisher_info, topic_name, new_value)
def _extract_array_info(self, type_str)
def _fill_message_slots(self, message, topic_name, expressions, counter)
def remove_publisher(self, publisher_id)
def _add_publisher(self, publisher_info)