rtlog.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- Python -*-
00003 # -*- coding: utf-8 -*-
00004 
00005 '''rtshell
00006 
00007 Copyright (C) 2009-2014
00008     Geoffrey Biggs
00009     RT-Synthesis Research Group
00010     Intelligent Systems Research Institute,
00011     National Institute of Advanced Industrial Science and Technology (AIST),
00012     Japan
00013     All rights reserved.
00014 Licensed under the Eclipse Public License -v 1.0 (EPL)
00015 http://www.opensource.org/licenses/eclipse-1.0.txt
00016 
00017 Implementation of the logging command.
00018 
00019 '''
00020 
00021 
00022 import optparse
00023 import os
00024 import os.path
00025 import rtctree.tree
00026 import rtctree.utils
00027 import sys
00028 import threading
00029 import time
00030 import traceback
00031 import OpenRTM_aist
00032 import RTC
00033 
00034 import comp_mgmt
00035 import modmgr
00036 import path
00037 import port_types
00038 import rtlog_comps
00039 import rts_exceptions
00040 import rtshell
00041 import simpkl_log
00042 import text_log
00043 
00044 
00045 def record_log(raw_paths, options, tree=None):
00046     event = threading.Event()
00047 
00048     if options.end is not None and options.end < 0:
00049         raise rts_exceptions.BadEndPointError
00050     if options.end is None and options.index:
00051         print >>sys.stderr, '{0}: WARNING: --index has no effect without '\
00052                 '--end'.format(os.path.basename(sys.argv[0]))
00053 
00054     mm = modmgr.ModuleMgr(verbose=options.verbose, paths=options.paths)
00055     mm.load_mods_and_poas(options.modules)
00056     if options.verbose:
00057         print >>sys.stderr, \
00058                 'Pre-loaded modules: {0}'.format(mm.loaded_mod_names)
00059 
00060     if options.timeout is not None:
00061         print >>sys.stderr, 'Recording for {0}s.'.format(options.timeout)
00062     else:
00063         if options.end is not None:
00064             if options.index:
00065                 print >>sys.stderr, 'Recording {0} entries.'.format(
00066                         int(options.end))
00067             else:
00068                 end_str = time.strftime('%Y-%m-%d %H:%M:%S',
00069                         time.localtime(options.end))
00070                 print >>sys.stderr, 'Recording until {0} ({1}).'.format(
00071                         end_str, options.end)
00072 
00073     if options.logger == 'simpkl':
00074         l_type = simpkl_log.SimplePickleLog
00075     elif options.logger == 'text':
00076         l_type = text_log.TextLog
00077     else:
00078         raise rts_exceptions.BadLogTypeError(options.logger)
00079 
00080     sources = port_types.parse_targets(raw_paths)
00081     if not tree:
00082         paths = [s[0] for s in sources]
00083         tree = rtctree.tree.RTCTree(paths=paths, filter=paths)
00084     port_specs = port_types.make_port_specs(sources, mm, tree)
00085     port_types.require_all_input(port_specs)
00086     if options.verbose:
00087         print >>sys.stderr, \
00088                 'Port specifications: {0}'.format([str(p) for p in port_specs])
00089 
00090     if options.end is None:
00091         end = -1 # Send -1 as the default
00092     else:
00093         end = options.end
00094     comp_name, mgr = comp_mgmt.make_comp('rtlog_recorder', tree,
00095             rtlog_comps.Recorder, port_specs, event=event,
00096             logger_type=l_type, filename=options.filename,
00097             lims_are_ind=options.index, end=end,
00098             verbose=options.verbose, rate=options.exec_rate)
00099     if options.verbose:
00100         print >>sys.stderr, 'Created component {0}'.format(comp_name)
00101     try:
00102         comp = comp_mgmt.find_comp_in_mgr(comp_name, mgr)
00103         comp_mgmt.connect(comp, port_specs, tree)
00104         comp_mgmt.activate(comp)
00105     except Exception, e:
00106         #comp_mgmt.shutdown(mgr)
00107         raise e
00108     try:
00109         if options.timeout is not None:
00110             event.wait(options.timeout)
00111             comp_mgmt.disconnect(comp)
00112             comp_mgmt.deactivate(comp)
00113         elif options.end is not None:
00114             event.wait()
00115             comp_mgmt.disconnect(comp)
00116             comp_mgmt.deactivate(comp)
00117         else:
00118             while True:
00119                 raw_input()
00120             # The manager will catch the Ctrl-C and shut down itself, so don't
00121             # disconnect/deactivate the component
00122     except KeyboardInterrupt:
00123         pass
00124     except EOFError:
00125         pass
00126     tree.give_away_orb()
00127     del tree
00128     comp_mgmt.shutdown(mgr)
00129 
00130 
00131 def play_log(raw_paths, options, tree=None):
00132     event = threading.Event()
00133 
00134     if not options.filename:
00135         raise rts_exceptions.NoLogFileNameError
00136     if options.start is not None and options.start < 0:
00137         raise rts_exceptions.BadStartPointError
00138     if options.end is not None and options.end < 0:
00139         raise rts_exceptions.BadEndPointError
00140     if options.end is None and options.start is None and options.index:
00141         print >>sys.stderr, '{0}: WARNING: --index has no effect without '\
00142                 '--start or --end'.format(os.path.basename(sys.argv[0]))
00143 
00144     mm = modmgr.ModuleMgr(verbose=options.verbose, paths=options.paths)
00145     mm.load_mods_and_poas(options.modules)
00146     if options.verbose:
00147         print >>sys.stderr, \
00148                 'Pre-loaded modules: {0}'.format(mm.loaded_mod_names)
00149 
00150     if options.timeout is not None:
00151         print >>sys.stderr, 'Playing for {0}s.'.format(options.timeout)
00152     else:
00153         if options.end is not None:
00154             if options.start is not None:
00155                 if options.index:
00156                     print >>sys.stderr, 'Playing from entry {0} to entry '\
00157                             '{1}.'.format(int(options.start), int(options.end))
00158                 else:
00159                     start_str = time.strftime('%Y-%m-%d %H:%M:%S',
00160                             time.localtime(options.start))
00161                     end_str = time.strftime('%Y-%m-%d %H:%M:%S',
00162                             time.localtime(options.end))
00163                     print >>sys.stderr, 'Playing from {0} ({1}) until {2} '\
00164                             '({3}).'.format(start_str, options.start, end_str,
00165                                     options.end)
00166             else:
00167                 if options.index:
00168                     print >>sys.stderr, 'Playing {0} entries.'.format(
00169                             int(options.end))
00170                 else:
00171                     end_str = time.strftime('%Y-%m-%d %H:%M:%S',
00172                             time.localtime(options.end))
00173                     print >>sys.stderr, 'Playing until {0} ({1}).'.format(
00174                             end_str, options.end)
00175         elif options.start is not None:
00176             if options.index:
00177                 print >>sys.stderr, 'Playing from entry {0}.'.format(
00178                         int(options.start))
00179             else:
00180                 start_str = time.strftime('%Y-%m-%d %H:%M:%S',
00181                         time.localtime(options.start))
00182                 print >>sys.stderr, 'Playing from {0} ({1}).'.format(start_str,
00183                         options.start)
00184 
00185     if options.logger == 'simpkl':
00186         l_type = simpkl_log.SimplePickleLog
00187     elif options.logger == 'text':
00188         raise rts_exceptions.UnsupportedLogTypeError('text', 'playback')
00189     else:
00190         raise rts_exceptions.BadLogTypeError(options.logger)
00191 
00192     targets = port_types.parse_targets(raw_paths)
00193     if not tree:
00194         paths = [t[0] for t in targets]
00195         tree = rtctree.tree.RTCTree(paths=paths, filter=paths)
00196     port_specs = port_types.make_port_specs(targets, mm, tree)
00197     if options.verbose:
00198         print >>sys.stderr, \
00199                 'Port specifications: {0}'.format([str(p) for p in port_specs])
00200     port_types.require_all_output(port_specs)
00201 
00202     if options.start is None:
00203         start = 0 # Send 0 as the default
00204     else:
00205         start = options.start
00206     if options.end is None:
00207         end = -1 # Send -1 as the default
00208     else:
00209         end = options.end
00210     comp_name, mgr = comp_mgmt.make_comp('rtlog_player', tree,
00211             rtlog_comps.Player, port_specs, event=event, logger_type=l_type,
00212             filename=options.filename, lims_are_ind=options.index, start=start,
00213             end=end, scale_rate=options.rate, abs_times=options.abs_times,
00214             ignore_times=options.ig_times, verbose=options.verbose,
00215             rate=options.exec_rate)
00216     if options.verbose:
00217         print >>sys.stderr, 'Created component {0}'.format(comp_name)
00218     comp = comp_mgmt.find_comp_in_mgr(comp_name, mgr)
00219     comp_mgmt.connect(comp, port_specs, tree)
00220     comp_mgmt.activate(comp)
00221     try:
00222         if options.timeout is not None:
00223             event.wait(options.timeout)
00224             comp_mgmt.disconnect(comp)
00225             try:
00226                 comp_mgmt.deactivate(comp)
00227             except rts_exceptions.DeactivateError:
00228                 # Don't care about this because the component will be shut down
00229                 # soon anyway
00230                 pass
00231         #elif options.end is not None:
00232         else:
00233             event.wait()
00234             comp_mgmt.disconnect(comp)
00235             try:
00236                 comp_mgmt.deactivate(comp)
00237             except rts_exceptions.DeactivateError:
00238                 # Don't care about this because the component will be shut down
00239                 # soon anyway
00240                 pass
00241         #else:
00242             #while True:
00243                 #raw_input()
00244             # The manager will catch the Ctrl-C and shut down itself, so don't
00245             # disconnect/deactivate the component
00246     except KeyboardInterrupt:
00247         pass
00248     except EOFError:
00249         pass
00250     tree.give_away_orb()
00251     del tree
00252     comp_mgmt.shutdown(mgr)
00253 
00254 
00255 def display_info(options):
00256     if not options.filename:
00257         raise rts_exceptions.NoLogFileNameError
00258 
00259     if options.logger == 'simpkl':
00260         l_type = simpkl_log.SimplePickleLog
00261     elif options.logger == 'text':
00262         raise rts_exceptions.UnsupportedLogTypeError('text', 'inspection')
00263     else:
00264         raise rts_exceptions.BadLogTypeError(options.logger)
00265 
00266     mm = modmgr.ModuleMgr(verbose=options.verbose, paths=options.paths)
00267     mm.load_mods_and_poas(options.modules)
00268     if options.verbose:
00269         print >>sys.stderr, \
00270                 'Pre-loaded modules: {0}'.format(mm.loaded_mod_names)
00271 
00272     statinfo = os.stat(options.filename)
00273     size = statinfo.st_size
00274     if size > 1024 * 1024 * 1024: # GiB
00275         size_str = '{0:.2f}GiB ({1}B)'.format(size / (1024.0 * 1024 * 1024), size)
00276     elif size > 1024 * 1024: # MiB
00277         size_str = '{0:.2f}MiB ({1}B)'.format(size / (1024.0 * 1024), size)
00278     elif size > 1024: # KiB
00279         size_str = '{0:.2f}KiB ({1}B)'.format(size / 1024.0, size)
00280     else:
00281         size_str = '{0}B'.format(size)
00282     log = l_type(filename=options.filename, mode='r', verbose=options.verbose)
00283 
00284     start_time, port_specs = log.metadata
00285     start_time_str = time.strftime('%Y-%m-%d %H:%M:%S',
00286             time.localtime(start_time))
00287     first_ind, first_time = log.start
00288     first_time_str = time.strftime('%Y-%m-%d %H:%M:%S',
00289             time.localtime(first_time.float))
00290     end_ind, end_time = log.end
00291     end_time_str = time.strftime('%Y-%m-%d %H:%M:%S',
00292             time.localtime(end_time.float))
00293 
00294     print 'Name: {0}'.format(options.filename)
00295     print 'Size: ' + size_str
00296     print 'Start time: {0} ({1})'.format(start_time_str, start_time)
00297     print 'First entry time: {0} ({1})'.format(first_time_str, first_time)
00298     print 'End time: {0} ({1})'.format(end_time_str, end_time)
00299     print 'Number of entries: {0}'.format(end_ind + 1)
00300     for ii, p in enumerate(port_specs):
00301         print 'Channel {0}'.format(ii + 1)
00302         print '  Name: {0}'.format(p.name)
00303         print '  Data type: {0} ({1})'.format(p.type_name, p.type)
00304         print '  Sources:'
00305         for r in p.raw:
00306             print '    {0}'.format(r)
00307 
00308 
00309 def main(argv=None, tree=None):
00310     usage = '''Usage: %prog [options] <path1>:<port1> [<path2>:<port2>...]
00311 Record data from output ports, or replay data into input ports.'''
00312     version = rtshell.RTSH_VERSION
00313     parser = optparse.OptionParser(usage=usage, version=version)
00314     parser.add_option('-a', '--absolute-times', dest='abs_times',
00315             action='store_true', default=False,
00316             help='Times from the logged data are sent as recorded during '
00317             'replay, rather than adjusted to the current timeframe. '
00318             '[Default: %default]')
00319     parser.add_option('-d', '--display-info', dest='display_info',
00320             action='store_true', default=False, help='Display the log '
00321             'information and exit.')
00322     parser.add_option('-e', '--end', dest='end', action='store', type='float',
00323             default=None,
00324             help='Time or entry index to stop recording or playback. Must be '
00325             'within the bounds of the log. Specify -1 to record forever or '
00326             'replay to the end of the log. Use --index to specify that this '
00327             'value is an index. [Default: %default]')
00328     parser.add_option('-f', '--filename', dest='filename', action='store',
00329             type='string', default='', help='File name of the log file to '
00330             'record to/playback from. If not specified for recording, a '
00331             'default will be created based on the current time. Must be '
00332             'specified for playback.')
00333     parser.add_option('--path', dest='paths', action='append', type='string',
00334             default=[], help='Extra module search paths to add to the '
00335             'PYTHONPATH.')
00336     parser.add_option('-i', '--index', dest='index', action='store_true',
00337             default=False, help='Interpret the start and end values as entry '
00338             'indices. [Default: %default]')
00339     parser.add_option('-l', '--logger', dest='logger', action='store',
00340             type='string', default='simpkl', help='The type of logger to '
00341             'use. The default is the SimplePickle logger. Alternatively, '
00342             'the text logger (specify using "text") may be used. The text '
00343             'logger does not support playback.')
00344     parser.add_option('-m', '--mod', dest='modules', action='append',
00345             type='string', default=[],
00346             help='Extra modules to import. If automatic module loading '
00347             'struggles with your data types, try listing the modules here. '
00348             'The module and its __POA partner will be imported.')
00349     parser.add_option('-n', '--ignore-times', dest='ig_times',
00350             action='store_true', default=False, help='Ignore the log '
00351             'timestamps and play back a fixed number of entries per '
00352             'execution. Use --rate to change the number played back per '
00353             'execution. The value of --rate will be treated as an integer '
00354             'in this case.')
00355     parser.add_option('-p', '--play', dest='play', action='store_true',
00356             default=False, help='Replay mode. [Default: %default]')
00357     parser.add_option('-r', '--rate', dest='rate', action='store',
00358             type='float', default=1.0,
00359             help='Scale the playback speed of the log. [Default: %default]')
00360     parser.add_option('-s', '--start', dest='start', action='store',
00361             type='float', default=None,
00362             help='Time or entry index to start playback from. Must be within '
00363             'the bounds of the log. Use --index to specify that this value '
00364             'is an index. [Default: %default]')
00365     parser.add_option('-t', '--timeout', dest='timeout', action='store',
00366             type='float', default=None, help='Record/replay data for this '
00367             'many seconds. This option overrides --start/--end.')
00368     parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
00369             default=False,
00370             help='Output verbose information. [Default: %default]')
00371     parser.add_option('-x', '--exec-rate', dest='exec_rate', action='store',
00372             type='float', default=100.0,
00373             help='Specify the rate in Hertz at which to run the component. '
00374             '[Default: %default]')
00375 
00376     if argv:
00377         sys.argv = [sys.argv[0]] + argv
00378     try:
00379         options, args = parser.parse_args()
00380     except optparse.OptionError, e:
00381         print >>sys.stderr, 'OptionError:', e
00382         return 1
00383 
00384     if len(args) < 1 and not options.display_info:
00385         print >>sys.stderr, usage
00386         return 1
00387 
00388     try:
00389         if options.display_info:
00390             display_info(options)
00391         elif options.play:
00392             play_log([path.cmd_path_to_full_path(p) for p in args],
00393                     options, tree)
00394         else:
00395             record_log([path.cmd_path_to_full_path(p) for p in args],
00396                     options, tree)
00397     except Exception, e:
00398         if options.verbose:
00399             traceback.print_exc()
00400         print >>sys.stderr, '{0}: {1}'.format(os.path.basename(sys.argv[0]), e)
00401         return 1
00402     return 0
00403 


rtshell
Author(s): Geoffrey Biggs
autogenerated on Fri Aug 28 2015 12:55:12