rxbag_app.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2009, Willow Garage, Inc.
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 Willow Garage, Inc. 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 OWNER 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 """
00034 Defines the rxbag wx.App.
00035 """
00036 
00037 import rospy
00038 
00039 import sys
00040 import threading
00041 import time
00042 
00043 import wx
00044 
00045 import rosbag
00046 
00047 from util.base_frame import BaseFrame
00048 from timeline        import Timeline
00049 
00050 class RxBagApp(wx.App):
00051     def __init__(self, options, args):
00052         self.options = options
00053         self.args    = args
00054         
00055         self.connected_to_ros = False
00056 
00057         wx.App.__init__(self)
00058     
00059     def OnInit(self):
00060         try:
00061             if self.options.record:
00062                 # Connect to ROS master
00063                 if not self.connect_to_ros():
00064                     raise Exception('recording requires connection to master')
00065 
00066                 # Get filename to record to
00067                 record_filename = time.strftime('%Y-%m-%d-%H-%M-%S.bag', time.localtime(time.time()))
00068                 if self.options.name:
00069                     record_filename = self.options.name
00070                     if not record_filename.endswith('.bag'):
00071                         record_filename += '.bag'
00072                 elif self.options.prefix:
00073                     prefix = self.options.prefix
00074                     if prefix.endswith('.bag'):
00075                         prefix = prefix[:-len('.bag')]
00076                     if prefix:
00077                         record_filename = '%s_%s' % (prefix, record_filename)
00078 
00079                 rospy.loginfo('Recording to %s.' % record_filename)
00080 
00081             # Create main timeline frame
00082             self.frame = BaseFrame(None, 'rxbag', 'Timeline')
00083             self.frame.BackgroundColour = wx.WHITE
00084             self.frame.Bind(wx.EVT_CLOSE, lambda e: wx.Exit())
00085 
00086             scroll = wx.ScrolledWindow(self.frame, -1)
00087             scroll.BackgroundColour = wx.WHITE
00088             
00089             timeline = Timeline(scroll, -1)
00090             timeline.Size = (100, 100)
00091             
00092             self.frame.Show()
00093             self.SetTopWindow(self.frame)
00094 
00095             timeline.SetFocus()
00096 
00097             if self.options.record:
00098                 timeline.record_bag(record_filename, all=self.options.all, topics=self.args, regex=self.options.regex, limit=self.options.limit)
00099             else:
00100                 RxBagInitThread(self, timeline)
00101 
00102         except Exception, ex:
00103             print >> sys.stderr, 'Error initializing application:', ex
00104             #import traceback
00105             #traceback.print_exc()
00106             return False
00107 
00108         return True
00109 
00110     def connect_to_ros(self, init_timeout=3):
00111         if self.connected_to_ros:
00112             return True
00113 
00114         # Attempt to connect to master node                                                                                                                                
00115         class InitNodeThread(threading.Thread):
00116             def __init__(self):
00117                 threading.Thread.__init__(self)
00118                 self.setDaemon(True)
00119                 self.inited = False
00120                 self.init_cv = threading.Condition()
00121     
00122             def run(self):
00123                 rospy.loginfo('Master found.  Connecting...')
00124                 rospy.init_node('rxbag', anonymous=True, disable_signals=True)
00125                 with self.init_cv:
00126                     self.inited = True
00127                     self.init_cv.notify_all()
00128     
00129         try:
00130             # Check whether ROS master is running                                                                                                                          
00131             master = rospy.get_master()
00132             master.getPid()
00133     
00134             # If so (i.e. no exception), attempt to initialize node                                                                                                        
00135             init_thread = InitNodeThread()
00136             with init_thread.init_cv:
00137                 init_thread.start()
00138                 init_thread.init_cv.wait(init_timeout)
00139     
00140             if init_thread.inited:
00141                 rospy.core.register_signals()
00142                 rospy.loginfo('Connected to ROS master.')
00143                 self.connected_to_ros = True
00144                 return True
00145             else:
00146                 rospy.logerr('Couldn\'t connect to ROS master.')
00147         except Exception:
00148             rospy.loginfo('ROS master not found.')
00149         
00150         return False
00151 
00152 class RxBagInitThread(threading.Thread):
00153     def __init__(self, app, timeline):
00154         threading.Thread.__init__(self)
00155         
00156         self.app      = app
00157         self.timeline = timeline
00158         
00159         self.start()
00160         
00161     def run(self):       
00162         for input_file in self.app.args:
00163             self.timeline.loading_filename = input_file               
00164 
00165             try:
00166                 self.timeline.add_bag(rosbag.Bag(input_file))
00167             except Exception, ex:
00168                 print >> sys.stderr, 'Error loading [%s]: %s' % (input_file, str(ex))
00169 
00170             self.timeline.loading_filename = None
00171 
00172         if self.app.options.start:
00173             playhead = self.timeline.start_stamp + rospy.Duration.from_sec(self.app.options.start)
00174             if playhead > self.timeline.end_stamp:
00175                 playhead = self.timeline.end_stamp
00176             elif playhead < self.timeline.start_stamp:
00177                 playhead = self.timeline.start_stamp
00178             
00179             self.timeline.playhead = playhead


rxbag
Author(s): Tim Field
autogenerated on Mon Oct 6 2014 07:26:07