plot.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 # Copyright (c) 2011, Dorian Scholz, TU Darmstadt
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions
00008 # are met:
00009 #
00010 #   * Redistributions of source code must retain the above copyright
00011 #     notice, this list of conditions and the following disclaimer.
00012 #   * Redistributions in binary form must reproduce the above
00013 #     copyright notice, this list of conditions and the following
00014 #     disclaimer in the documentation and/or other materials provided
00015 #     with the distribution.
00016 #   * Neither the name of the TU Darmstadt nor the names of its
00017 #     contributors may be used to endorse or promote products derived
00018 #     from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 
00033 import argparse
00034 
00035 from python_qt_binding import QT_BINDING
00036 from python_qt_binding.QtCore import qDebug
00037 from rqt_gui_py.plugin import Plugin
00038 
00039 from rqt_py_common.ini_helper import pack, unpack
00040 
00041 from .plot_widget import PlotWidget
00042 
00043 from .data_plot import DataPlot
00044 
00045 
00046 class Plot(Plugin):
00047 
00048     def __init__(self, context):
00049         super(Plot, self).__init__(context)
00050         self.setObjectName('Plot')
00051 
00052         self._context = context
00053 
00054         self._args = self._parse_args(context.argv())
00055         self._widget = PlotWidget(
00056             initial_topics=self._args.topics, start_paused=self._args.start_paused)
00057         self._data_plot = DataPlot(self._widget)
00058 
00059         # disable autoscaling of X, and set a sane default range
00060         self._data_plot.set_autoscale(x=False)
00061         self._data_plot.set_autoscale(y=DataPlot.SCALE_EXTEND | DataPlot.SCALE_VISIBLE)
00062         self._data_plot.set_xlim([0, 10.0])
00063 
00064         self._widget.switch_data_plot_widget(self._data_plot)
00065         if context.serial_number() > 1:
00066             self._widget.setWindowTitle(
00067                 self._widget.windowTitle() + (' (%d)' % context.serial_number()))
00068         context.add_widget(self._widget)
00069 
00070     def _parse_args(self, argv):
00071         parser = argparse.ArgumentParser(prog='rqt_plot', add_help=False)
00072         Plot.add_arguments(parser)
00073         args = parser.parse_args(argv)
00074 
00075         # convert topic arguments into topic names
00076         topic_list = []
00077         for t in args.topics:
00078             # c_topics is the list of topics to plot
00079             c_topics = []
00080             # compute combined topic list, t == '/foo/bar1,/baz/bar2'
00081             for sub_t in [x for x in t.split(',') if x]:
00082                 # check for shorthand '/foo/field1:field2:field3'
00083                 if ':' in sub_t:
00084                     base = sub_t[:sub_t.find(':')]
00085                     # the first prefix includes a field name, so save then strip it off
00086                     c_topics.append(base)
00087                     if not '/' in base:
00088                         parser.error("%s must contain a topic and field name" % sub_t)
00089                     base = base[:base.rfind('/')]
00090 
00091                     # compute the rest of the field names
00092                     fields = sub_t.split(':')[1:]
00093                     c_topics.extend(["%s/%s" % (base, f) for f in fields if f])
00094                 else:
00095                     c_topics.append(sub_t)
00096             # 1053: resolve command-line topic names
00097             import rosgraph
00098             c_topics = [rosgraph.names.script_resolve_name('rqt_plot', n) for n in c_topics]
00099             if type(c_topics) == list:
00100                 topic_list.extend(c_topics)
00101             else:
00102                 topic_list.append(c_topics)
00103         args.topics = topic_list
00104 
00105         return args
00106 
00107     @staticmethod
00108     def add_arguments(parser):
00109         group = parser.add_argument_group('Options for rqt_plot plugin')
00110         group.add_argument('-P', '--pause', action='store_true', dest='start_paused',
00111                            help='Start in paused state')
00112         group.add_argument('-e', '--empty', action='store_true', dest='start_empty',
00113                            help='Start without restoring previous topics')
00114         group.add_argument('topics', nargs='*', default=[], help='Topics to plot')
00115 
00116     def _update_title(self):
00117         self._widget.setWindowTitle(self._data_plot.getTitle())
00118         if self._context.serial_number() > 1:
00119             self._widget.setWindowTitle(
00120                 self._widget.windowTitle() + (' (%d)' % self._context.serial_number()))
00121 
00122     def save_settings(self, plugin_settings, instance_settings):
00123         self._data_plot.save_settings(plugin_settings, instance_settings)
00124         instance_settings.set_value('autoscroll', self._widget.autoscroll_checkbox.isChecked())
00125         instance_settings.set_value('topics', pack(self._widget._rosdata.keys()))
00126 
00127     def restore_settings(self, plugin_settings, instance_settings):
00128         autoscroll = instance_settings.value('autoscroll', True) in [True, 'true']
00129         self._widget.autoscroll_checkbox.setChecked(autoscroll)
00130         self._data_plot.autoscroll(autoscroll)
00131 
00132         self._update_title()
00133 
00134         if len(self._widget._rosdata.keys()) == 0 and not self._args.start_empty:
00135             topics = unpack(instance_settings.value('topics', []))
00136             if topics:
00137                 for topic in topics:
00138                     self._widget.add_topic(topic)
00139 
00140         self._data_plot.restore_settings(plugin_settings, instance_settings)
00141 
00142     def trigger_configuration(self):
00143         self._data_plot.doSettingsDialog()
00144         self._update_title()
00145 
00146     def shutdown_plugin(self):
00147         self._widget.clean_up_subscribers()


rqt_plot
Author(s): Dorian Scholz
autogenerated on Sun Mar 17 2019 02:29:34