This code reads binary file. Read data is converted into signed values and gets plotted if the user wants it.
Data looks as below:
00000000: 0800 01dc 0500 02a4 0000 88ff f918 a9ff ................ 00000010: fa53 88ff 3200 0161 2d00 029a 2e00 feff .S..2..a-....... 00000020: f933 f6ff fa14 efff ebff f9bf eaff fa0e .3.............. 00000030: eaff 2500 0132 1700 0232 1f00 eeff f9ef ..%..2...2...... 00000040: eeff fa73 e6ff f3ff f9a6 efff fa9c f5ff ...s............ 00000050: ecff f92c ebff fa69 eaff ffff 0188 0100 ...,...i........ 00000060: fabd f6ff 0500 01d6 0300 0211 0100 1400 ................ 00000070: 0177 1400 0205 1400 0f00 017b 0e00 02e5 .w.........{.... 00000080: 0400 ffff f949 ffff fab3 fbff 0000 01f9 .....I.......... 00000090: 0100 fa3f f3ff ffff f94c fcff fa2e f7ff ...?.....L...... 000000a0: 0200 01ad 0200 027a 0100 1b00 015c 1500 .......z.....\.. 000000b0: 026a 1400 1200 0183 0d00 02cf 0e00 1200 .j.............. 000000c0: 01f0 0a00 02c1 0d00 ffff f977 f9ff fa48 ...........w...H 000000d0: faff 1000 01eb 0400 02cb 0000 1400 0178 ...............x
Code:
import matplotlib.pyplot as plt import numpy as np import matplotlib.animation as animation import struct from optparse import OptionParser from collections import OrderedDict import sys import binascii import time import math def twos_complement(hexstr, bits): value = int(hexstr,16) if value & (1 << (bits-1)): value -= 1 << bits return value def reverse_digits(s): if len(s) != 4: print("wrong length passed %d!!"% (len(s))) return None return s[2:] + s[0:2] params_information = OrderedDict([("division", (5, 5)), ("fast_velocity", (30, -30)), ("test_velocity", (60, -60)), ("test_position", (22, -22)), ("another_test_velocity", (28, -28))]) class TESTParams(): def __init__(self, file_name): self.file_name = file_name self.all_params = {} self.param_size = 20 def get_param(self, param): return self.all_params[param] def plot_param(self, param): # Create a figure of size 8x6 inches, 80 dots per inch plt.figure(figsize=(8, 6), dpi=80) # Create a new subplot from a grid of 1x1 plt.subplot(1, 1, 1) plt.xlabel(str(param)) plt.ylabel("limits") x = np.linspace(params_information[param][0], params_information[param][1], num=len(self.all_params[param])) plt.plot(x, self.all_params[param]) plt.show() def get_all_params(self): """ gets division/fast/test/another_test velocity and position from file file format is binary and it has data in below format repeated till EOF struct __attribute__((__packed__)) test_data { uint16_t division; int16_t fast_velocity; int16_t test_velocity; int16_t test_position; int16_t another_test_velocity; }; Below code does converts raw characters read from file into signed 16 bit numbers before adding to the dictionary. """ with open(self.file_name) as file: data = file.read() hex_data = binascii.hexlify(data) for i in range(0, len(hex_data), self.param_size): test_data = hex_data[i:i+self.param_size] j = 0 division = 0 for param in params_information: if not param in self.all_params: self.all_params[param] = [] if param == "division": division = float(twos_complement(reverse_digits(test_data[j:j+4]), 16)) if division == 0: print("division is 0!!") return self.all_params[param].append(float(division)) else: self.all_params[param].append(float(twos_complement(reverse_digits(test_data[j:j+4]), 16)/division)) j += 4 def main(): parser = OptionParser(usage="usage: %prog [options] filename -p -v", version="%prog 1.0") parser.add_option("-f", "--file", dest='filename', help="file name to get test data from") parser.add_option("-p", "--print_all_params", default=False, dest='print_all_params', help="print all params division/fast/test/another_test velocities and position", action='store_true') parser.add_option("-o", "--plot_param", default=False, dest='plot_param', help="plot param, pass - division , fast_velocity, test_velocity , test_position another_test_velocity") (options, args) = parser.parse_args() if not options.filename: parser.error('Filename not given') p = TESTParams(options.filename) p.get_all_params() if options.verify and p.verify_all_params(): pass if options.print_all_params: for i, j, k, l, m in zip(p.get_param("division"), p.get_param("fast_velocity"), p.get_param("test_velocity"), p.get_param("test_position"), p.get_param("another_test_velocity")): print("division [%f] fast_velocity[%f] test_velocity[%f] test_position[%f] another_test_velocity[%f]"% (i, j, k, l, m)) if options.plot_param in params_information: p.plot_param(options.plot_param) if __name__ == '__main__': main()