def convert_ulog2csv(ulog_file_name, messages, output, delimiter, disable_str_exceptions=False): """ Coverts and ULog file to a CSV file. :param ulog_file_name: The ULog filename to open and read :param messages: A list of message names :param output: Output file path :param delimiter: CSV delimiter :return: None """ msg_filter = messages.split(',') if messages else None ulog = ULog(ulog_file_name, msg_filter, disable_str_exceptions) data = ulog.data_list output_file_prefix = ulog_file_name # strip '.ulg' if output_file_prefix.lower().endswith('.ulg'): output_file_prefix = output_file_prefix[:-4] # write to different output path? if output: base_name = os.path.basename(output_file_prefix) output_file_prefix = os.path.join(output, base_name) for d in data: fmt = '{0}_{1}_{2}.csv' output_file_name = fmt.format(output_file_prefix, d.name, d.multi_id) fmt = 'Writing {0} ({1} data points)' # print(fmt.format(output_file_name, len(d.data['timestamp']))) with open(output_file_name, 'w') as csvfile: # use same field order as in the log, except for the timestamp data_keys = [f.field_name for f in d.field_data] data_keys.remove('timestamp') data_keys.insert( 0, 'timestamp') # we want timestamp at first position # we don't use np.savetxt, because we have multiple arrays with # potentially different data types. However the following is quite # slow... # write the header csvfile.write(delimiter.join(data_keys) + '\n') # write the data last_elem = len(data_keys) - 1 for i in range(len(d.data['timestamp'])): for k in range(len(data_keys)): csvfile.write(str(d.data[data_keys[k]][i])) if k != last_elem: csvfile.write(delimiter) csvfile.write('\n')
def show_info(ulog, verbose): """Show general information from an ULog""" m1, s1 = divmod(int(ulog.start_timestamp / 1e6), 60) h1, m1 = divmod(m1, 60) m2, s2 = divmod(int((ulog.last_timestamp - ulog.start_timestamp) / 1e6), 60) h2, m2 = divmod(m2, 60) print( "Logging start time: {:d}:{:02d}:{:02d}, duration: {:d}:{:02d}:{:02d}". format(h1, m1, s1, h2, m2, s2)) dropout_durations = [dropout.duration for dropout in ulog.dropouts] if len(dropout_durations) == 0: print("No Dropouts") else: print( "Dropouts: count: {:}, total duration: {:.1f} s, max: {:} ms, mean: {:} ms" .format(len(dropout_durations), sum(dropout_durations) / 1000., max(dropout_durations), int(sum(dropout_durations) / len(dropout_durations)))) version = ulog.get_version_info_str() if not version is None: print('SW Version: {}'.format(version)) print("Info Messages:") for k in sorted(ulog.msg_info_dict): if not k.startswith('perf_') or verbose: print(" {0}: {1}".format(k, ulog.msg_info_dict[k])) if len(ulog.msg_info_multiple_dict) > 0: if verbose: print("Info Multiple Messages:") for k in sorted(ulog.msg_info_multiple_dict): print(" {0}: {1}".format(k, ulog.msg_info_multiple_dict[k])) else: print("Info Multiple Messages: {}".format(", ".join([ "[{}: {}]".format(k, len(ulog.msg_info_multiple_dict[k])) for k in sorted(ulog.msg_info_multiple_dict) ]))) print("") print("{:<41} {:7}, {:10}".format("Name (multi id, message size in bytes)", "number of data points", "total bytes")) data_list_sorted = sorted(ulog.data_list, key=lambda d: d.name + str(d.multi_id)) for d in data_list_sorted: message_size = sum( [ULog.get_field_size(f.type_str) for f in d.field_data]) num_data_points = len(d.data['timestamp']) name_id = "{:} ({:}, {:})".format(d.name, d.multi_id, message_size) print(" {:<40} {:7d} {:10d}".format(name_id, num_data_points, message_size * num_data_points))
def main(): """Commande line interface""" parser = argparse.ArgumentParser( description='Display information from an ULog file') parser.add_argument('filename', metavar='file.ulg', help='ULog input file') parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='Verbose output', default=False) parser.add_argument('-m', '--message', dest='message', help='Show a specific Info Multiple Message') parser.add_argument('-n', '--newline', dest='newline', action='store_true', help='Add newline separators (only with --message)', default=False) parser.add_argument('-i', '--ignore', dest='ignore', action='store_true', help='Ignore string parsing exceptions', default=False) args = parser.parse_args() ulog_file_name = args.filename disable_str_exceptions = args.ignore ulog = ULog(ulog_file_name, None, disable_str_exceptions) message = args.message if message: separator = "" if args.newline: separator = "\n" if len(ulog.msg_info_multiple_dict ) > 0 and message in ulog.msg_info_multiple_dict: message_info_multiple = ulog.msg_info_multiple_dict[message] for i, m in enumerate(message_info_multiple): print("# {} {}:".format(message, i)) print(separator.join(m)) else: print("message {} not found".format(message)) else: show_info(ulog, args.verbose)