00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 import roslib;
00012 roslib.load_manifest('art_servo')
00013
00014 import rospy
00015 from art_msgs.msg import BrakeCommand
00016 from art_msgs.msg import BrakeState
00017
00018 import sys
00019 import getopt
00020 import os
00021 import threading
00022
00023 import plot_brake
00024
00025 class commandThread(threading.Thread):
00026 "Separate thread for shell commands."
00027
00028 def __init__(self, command):
00029 "Shell command thread initialization."
00030 self.command = command
00031 threading.Thread.__init__(self)
00032
00033 def run(self):
00034 "Run a shell command in this thread."
00035 rc = os.system(self.command)
00036 rospy.signal_shutdown('bag finished')
00037 return rc
00038
00039 class brakeTopics:
00040 "Monitor ROS brake topics for data analysis."
00041
00042 def __init__(self, name=None):
00043 "Constructor method."
00044
00045
00046 if name:
00047 self.name = name
00048 else:
00049 self.name = 'brake'
00050
00051 self.plt = plot_brake.brakeData()
00052
00053 def get_cmd(self, cmd):
00054 "ROS callback for /brake/cmd topic."
00055 self.plt.set_cmd(cmd.header.stamp.to_sec(), cmd.position)
00056
00057 def get_state(self, state):
00058 "ROS callback for /brake/state topic."
00059 self.plt.set_state(state.header.stamp.to_sec(), state.position,
00060 state.potentiometer, state.encoder, state.pressure)
00061
00062 def get_bag(self, filename):
00063 "Acquire brake topic data from ROS bag."
00064 filename = os.path.expanduser(filename)
00065 self.name, fileext = os.path.splitext(os.path.basename(filename))
00066 commandThread('rosplay -a ' + filename).start()
00067 self.get_data(False)
00068
00069 def get_data(self, verbose=True):
00070 "Acquire brake topic data until ROS shutdown."
00071 rospy.Subscriber('brake/cmd', BrakeCommand, self.get_cmd)
00072 rospy.Subscriber('brake/state', BrakeState, self.get_state)
00073 rospy.init_node('rosbrake')
00074 if verbose:
00075 print('begin acquiring brake data -- interrupt when finished')
00076 try:
00077 rospy.spin()
00078 except rospy.ROSInterruptException: pass
00079 if verbose:
00080 print('done acquiring brake data')
00081
00082 def plot(self, save=False, plotall=False):
00083 """ Plot some interesting data from the brake test run.
00084
00085 When save=True write the figures to PNG files, otherwise show
00086 them interactively.
00087 """
00088 self.plt.name = self.name
00089 if plotall:
00090 self.plt.plot(save)
00091 else:
00092 self.plt.plot_position(save)
00093
00094
00095 b = brakeTopics()
00096
00097 def usage(progname):
00098 "Print usage message."
00099 print("\n" + str(progname) + """[-h] [ <file.bag> ]
00100
00101 -a, --all generate all available plots (default: just position)
00102 -h, --help print this message
00103 -i, --interactive display plots to terminal (default: save as files)
00104
00105 <file.bag>\tname of ROS bag file to analyze
00106
00107 If a bag file is specified, read brake topics from it, saving plots of
00108 the data. Otherwise, read the ROS topics directly from the running
00109 system.
00110 """)
00111
00112
00113 def main(argv=None):
00114 "Main program, called as a script or interactively."
00115
00116 if argv is None:
00117 argv = sys.argv
00118 argv = rospy.myargv(argv)
00119
00120
00121 progname = os.path.basename(argv[0])
00122 if progname is "":
00123 progname = "rosbrake.py"
00124
00125
00126 try:
00127 opts, files = getopt.gnu_getopt(argv[1:], 'ahi',
00128 ('all', 'help', 'interactive'))
00129 except getopt.error, msg:
00130 print(msg)
00131 print("for help use --help")
00132 return 9
00133
00134 plotall = False
00135 save = True
00136
00137 for k,v in opts:
00138 if k in ("-a", "--all"):
00139 plotall = True
00140 if k in ("-h", "--help"):
00141 usage(progname)
00142 return 2
00143 if k in ("-i", "--interactive"):
00144 save = False
00145
00146 if len(files) < 1:
00147 print("no bag file, reading brake topics directly")
00148 b.get_data()
00149 b.plot(save, plotall)
00150
00151 elif len(files) == 1:
00152 print("Analyzing " + files[0])
00153 b.get_bag(files[0])
00154 b.plot(save, plotall)
00155
00156 else:
00157 print("only one ROS bag file can be processed at a time")
00158 usage(progname)
00159 return 9
00160
00161 return 0
00162
00163
00164 if __name__ == "__main__":
00165
00166 sys.exit(main())