PageRenderTime 100ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/sw/tools/calibration/calib.py

http://github.com/pchickey/paparazzi-linux-release
Python | 149 lines | 140 code | 2 blank | 7 comment | 2 complexity | 800264ef0b874d5f337320df8a34af06 MD5 | raw file
Possible License(s): GPL-2.0
  1. #
  2. # My first attempt at python
  3. # calibrate accelerometer
  4. #
  5. import re
  6. import scipy
  7. from scipy import optimize
  8. from scipy import linalg
  9. from pylab import *
  10. #
  11. # parse the log
  12. #
  13. def read_log(ac_id, filename, sensor):
  14. f = open(filename, 'r')
  15. pattern = re.compile("(\S+) "+ac_id+" IMU_"+sensor+"_RAW (\S+) (\S+) (\S+)")
  16. list_meas = []
  17. while 1:
  18. line = f.readline().strip()
  19. if line == '':
  20. break
  21. m=re.match(pattern, line)
  22. if m:
  23. list_meas.append([float(m.group(2)), float(m.group(3)), float(m.group(4))])
  24. return scipy.array(list_meas)
  25. #
  26. # select only non-noisy data
  27. #
  28. def filter_meas(meas, window_size, noise_threshold):
  29. filtered_meas = []
  30. filtered_idx = []
  31. for i in range(window_size,len(meas)-window_size):
  32. noise = meas[i-window_size:i+window_size,:].std(axis=0)
  33. if linalg.norm(noise) < noise_threshold:
  34. filtered_meas.append(meas[i,:])
  35. filtered_idx.append(i)
  36. return scipy.array(filtered_meas), filtered_idx
  37. #
  38. # initial boundary based calibration
  39. #
  40. def get_min_max_guess(meas, scale):
  41. max_meas = meas[:,:].max(axis=0)
  42. min_meas = meas[:,:].min(axis=0)
  43. n = (max_meas + min_meas) / 2
  44. sf = 2*scale/(max_meas - min_meas)
  45. return scipy.array([n[0], n[1], n[2], sf[0], sf[1], sf[2]])
  46. #
  47. # scale the set of measurements
  48. #
  49. def scale_measurements(meas, p):
  50. l_comp = [];
  51. l_norm = [];
  52. for m in meas[:,]:
  53. sm = (m - p[0:3])*p[3:6]
  54. l_comp.append(sm)
  55. l_norm.append(linalg.norm(sm))
  56. return scipy.array(l_comp), scipy.array(l_norm)
  57. #
  58. # print xml for airframe file
  59. #
  60. def print_xml(p, sensor, res):
  61. print ""
  62. print "<define name=\""+sensor+"_X_NEUTRAL\" value=\""+str(int(round(p[0])))+"\"/>"
  63. print "<define name=\""+sensor+"_Y_NEUTRAL\" value=\""+str(int(round(p[1])))+"\"/>"
  64. print "<define name=\""+sensor+"_Z_NEUTRAL\" value=\""+str(int(round(p[2])))+"\"/>"
  65. print "<define name=\""+sensor+"_X_SENS\" value=\""+str(p[3]*2**res)+"\" integer=\"16\"/>"
  66. print "<define name=\""+sensor+"_Y_SENS\" value=\""+str(p[4]*2**res)+"\" integer=\"16\"/>"
  67. print "<define name=\""+sensor+"_Z_SENS\" value=\""+str(p[5]*2**res)+"\" integer=\"16\"/>"
  68. filename = 'log_accel_booz2_a2'
  69. ac_id = "151"
  70. if 1:
  71. sensor = "ACCEL"
  72. sensor_ref = 9.81
  73. sensor_res = 10
  74. noise_window = 20;
  75. noise_threshold = 40;
  76. else:
  77. sensor = "MAG"
  78. sensor_ref = 1.
  79. sensor_res = 11
  80. noise_window = 10;
  81. noise_threshold = 1000;
  82. print "reading file "+filename+" for aircraft "+ac_id+" and sensor "+sensor
  83. measurements = read_log(ac_id, filename, sensor)
  84. print "found "+str(len(measurements))+" records"
  85. flt_meas, flt_idx = filter_meas(measurements, noise_window, noise_threshold)
  86. print "remaining "+str(len(flt_meas))+" after low pass"
  87. p0 = get_min_max_guess(flt_meas, sensor_ref)
  88. cp0, np0 = scale_measurements(flt_meas, p0)
  89. print "initial guess : "+str(np0.mean())+" "+str(np0.std())
  90. print p0
  91. def err_func(p,meas,y):
  92. cp, np = scale_measurements(meas, p)
  93. err = y*scipy.ones(len(meas)) - np
  94. return err
  95. p1, success = optimize.leastsq(err_func, p0[:], args=(flt_meas, sensor_ref))
  96. cp1, np1 = scale_measurements(flt_meas, p1)
  97. print "optimized guess : "+str(np1.mean())+" "+str(np1.std())
  98. print p1
  99. print_xml(p1, sensor, sensor_res)
  100. subplot(3,1,1)
  101. plot(measurements[:,0])
  102. plot(measurements[:,1])
  103. plot(measurements[:,2])
  104. plot(flt_idx, flt_meas[:,0], 'ro')
  105. plot(flt_idx, flt_meas[:,1], 'ro')
  106. plot(flt_idx, flt_meas[:,2], 'ro')
  107. subplot(3,2,3)
  108. plot(cp0[:,0]);
  109. plot(cp0[:,1]);
  110. plot(cp0[:,2]);
  111. plot(-sensor_ref*scipy.ones(len(flt_meas)));
  112. plot(sensor_ref*scipy.ones(len(flt_meas)));
  113. subplot(3,2,4)
  114. plot(np0);
  115. plot(sensor_ref*scipy.ones(len(flt_meas)));
  116. subplot(3,2,5)
  117. plot(cp1[:,0]);
  118. plot(cp1[:,1]);
  119. plot(cp1[:,2]);
  120. plot(-sensor_ref*scipy.ones(len(flt_meas)));
  121. plot(sensor_ref*scipy.ones(len(flt_meas)));
  122. subplot(3,2,6)
  123. plot(np1);
  124. plot(sensor_ref*scipy.ones(len(flt_meas)));
  125. show();