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 class Plot(Plugin):
00046 
00047     def __init__(self, context):
00048         super(Plot, self).__init__(context)
00049         self.setObjectName('Plot')
00050 
00051         self._context = context
00052 
00053         self._args = self._parse_args(context.argv())
00054         self._widget = PlotWidget(initial_topics=self._args.topics, start_paused=self._args.start_paused)
00055         self._data_plot = DataPlot(self._widget)
00056 
00057         # disable autoscaling of X, and set a sane default range
00058         self._data_plot.set_autoscale(x=False)
00059         self._data_plot.set_autoscale(y=DataPlot.SCALE_EXTEND|DataPlot.SCALE_VISIBLE)
00060         self._data_plot.set_xlim([0, 10.0])
00061 
00062         self._widget.switch_data_plot_widget(self._data_plot)
00063         if context.serial_number() > 1:
00064             self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number()))
00065         context.add_widget(self._widget)
00066 
00067     def _parse_args(self, argv):
00068         parser = argparse.ArgumentParser(prog='rqt_plot', add_help=False)
00069         Plot.add_arguments(parser)
00070         args = parser.parse_args(argv)
00071 
00072         # convert topic arguments into topic names
00073         topic_list = []
00074         for t in args.topics:
00075             # c_topics is the list of topics to plot
00076             c_topics = []
00077             # compute combined topic list, t == '/foo/bar1,/baz/bar2'
00078             for sub_t in [x for x in t.split(',') if x]:
00079                 # check for shorthand '/foo/field1:field2:field3'
00080                 if ':' in sub_t:
00081                     base = sub_t[:sub_t.find(':')]
00082                     # the first prefix includes a field name, so save then strip it off
00083                     c_topics.append(base)
00084                     if not '/' in base:
00085                         parser.error("%s must contain a topic and field name" % sub_t)
00086                     base = base[:base.rfind('/')]
00087 
00088                     # compute the rest of the field names
00089                     fields = sub_t.split(':')[1:]
00090                     c_topics.extend(["%s/%s" % (base, f) for f in fields if f])
00091                 else:
00092                     c_topics.append(sub_t)
00093             # #1053: resolve command-line topic names
00094             import rosgraph
00095             c_topics = [rosgraph.names.script_resolve_name('rqt_plot', n) for n in c_topics]
00096             if type(c_topics) == list:
00097                 topic_list.extend(c_topics)
00098             else:
00099                 topic_list.append(c_topics)
00100         args.topics = topic_list
00101 
00102         return args
00103 
00104     @staticmethod
00105     def add_arguments(parser):
00106         group = parser.add_argument_group('Options for rqt_plot plugin')
00107         group.add_argument('-P', '--pause', action='store_true', dest='start_paused',
00108             help='Start in paused state')
00109         group.add_argument('-e', '--empty', action='store_true', dest='start_empty',
00110             help='Start without restoring previous topics')
00111         group.add_argument('topics', nargs='*', default=[], help='Topics to plot')
00112 
00113     def _update_title(self):
00114         self._widget.setWindowTitle(self._data_plot.getTitle())
00115         if self._context.serial_number() > 1:
00116             self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % self._context.serial_number()))
00117 
00118     def save_settings(self, plugin_settings, instance_settings):
00119         self._data_plot.save_settings(plugin_settings, instance_settings)
00120         instance_settings.set_value('autoscroll', self._widget.autoscroll_checkbox.isChecked())
00121         instance_settings.set_value('topics', pack(self._widget._rosdata.keys()))
00122 
00123     def restore_settings(self, plugin_settings, instance_settings):
00124         autoscroll = instance_settings.value('autoscroll', True) in [True, 'true']
00125         self._widget.autoscroll_checkbox.setChecked(autoscroll)
00126         self._data_plot.autoscroll(autoscroll)
00127 
00128         self._data_plot.restore_settings(plugin_settings, instance_settings)
00129         self._update_title()
00130 
00131         if len(self._widget._rosdata.keys()) == 0 and not self._args.start_empty:
00132             topics = unpack(instance_settings.value('topics', []))
00133             if topics:
00134                 for topic in topics:
00135                     self._widget.add_topic(topic)
00136 
00137     def trigger_configuration(self):
00138         self._data_plot.doSettingsDialog()
00139         self._update_title()
00140 
00141     def shutdown_plugin(self):
00142         self._widget.clean_up_subscribers()


rqt_plot
Author(s): Dorian Scholz
autogenerated on Mon Oct 6 2014 07:15:32