Go to the documentation of this file.00001
00002
00003 import roslib
00004 roslib.load_manifest("sensor_msgs")
00005 roslib.load_manifest("message_filters")
00006 roslib.load_manifest("rxtools")
00007 import rospy
00008 import rxtools
00009 import rxtools.rosplot
00010 import sys
00011 import message_filters
00012 from optparse import OptionParser, OptionValueError
00013
00014 topic_desc = []
00015 fd = False
00016 class Error(Exception):
00017 pass
00018 class InvalidTopic(Error):
00019 pass
00020 class NoFieldName(Error):
00021 pass
00022 class NotSupportedFeature(Error):
00023 pass
00024
00025 def usage():
00026 print """usage:
00027 bag_to_ssv OUTPUT_FILE TOPIC1 [TOPIC2 TOPIC3 ...]"""
00028 return 1
00029
00030 def time_axeq(self, other):
00031 if not isinstance(other, roslib.rostime.Time):
00032 return False
00033 secs = abs(self.to_sec() - other.to_sec())
00034
00035 if secs < tolerance:
00036 return True
00037 else:
00038 return False
00039
00040
00041 def time_cmp(self, other):
00042 if not isinstance(other, roslib.rostime.Time):
00043 raise TypeError("cannot compare to non-Time")
00044 secs = self.to_sec() - other.to_sec()
00045 if abs(secs) < tolerance:
00046 return 0
00047 if secs > 0:
00048 return 1
00049 return -1
00050
00051 def time_hash(self):
00052 return ("%s.%s"%(self.secs, self.nsecs / int(tolerance * 1e9))) .__hash__()
00053
00054
00055 def callback(*values):
00056 for (v, evals) in zip(values, topic_desc):
00057 for f in evals[1]:
00058 v = f(v)
00059 fd.write(str(v) + deliminator)
00060 fd.write("\n")
00061 fd.flush()
00062
00063 def main(args):
00064 global fd
00065 output_file = args[1]
00066 fd = open(output_file, "w")
00067 topics = args[2:]
00068 subscribers = []
00069
00070 for topic in topics:
00071 (topic_type, real_topic, rest) = rxtools.rosplot.get_topic_type(topic)
00072 if rest == '':
00073 raise NoFieldName("you need to specify filed")
00074 e = rxtools.rosplot.generate_field_evals(rest)
00075
00076
00077 topic_desc.append([real_topic, e])
00078 data_class = roslib.message.get_message_class(topic_type)
00079 subscribers.append(message_filters.Subscriber(real_topic, data_class))
00080 print "subscribing to %s" % (real_topic)
00081
00082 fd.write(topic + deliminator)
00083 fd.write("\n")
00084 ts = message_filters.TimeSynchronizer(subscribers, 100)
00085
00086 ts.registerCallback(callback)
00087 try:
00088 rospy.spin()
00089 finally:
00090 fd.close()
00091
00092 def parse_options(args):
00093 parser = OptionParser(usage="topics_to_ssv [options] OUTPUT_FILE_NAME TOPICNAME1 TOPICNAME2 ...")
00094 parser.add_option("-d", "--deliminator", dest = "deliminator",
00095 default = ";",
00096 help = "specify deliminator character (or string). the default value is ;",
00097 action = "store")
00098 parser.add_option("-t", "--tolerance", dest = "tolerance",
00099 default = "0.04",
00100 help = """specify timestamp tolerance in sec. the default value is 0.04""",
00101 action = "store")
00102 (options, args) = parser.parse_args(args)
00103
00104 global tolerance
00105 global deliminator
00106 deliminator = options.deliminator
00107 tolerance = float(options.tolerance)
00108 return args
00109
00110 if __name__ == "__main__":
00111 rospy.init_node("bag_to_ssv")
00112 args = parse_options(sys.argv)
00113 setattr(roslib.rostime.Time, "__eq__", time_axeq)
00114 setattr(roslib.rostime.Time, "__cmp__", time_cmp)
00115 setattr(roslib.rostime.Time, "__hash__", time_hash)
00116 main(args)