magfit_compassmot.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/env python
  2. '''
  3. estimate COMPASS_MOT_* parameters for throttle based compensation
  4. '''
  5. from __future__ import print_function
  6. from builtins import range
  7. import math
  8. from argparse import ArgumentParser
  9. parser = ArgumentParser(description=__doc__)
  10. parser.add_argument("--condition",dest="condition", default=None, help="select packets by condition")
  11. parser.add_argument("logs", metavar="LOG", nargs="+")
  12. args = parser.parse_args()
  13. from pymavlink import mavutil
  14. from pymavlink.rotmat import Vector3
  15. def mag_error(p, data):
  16. cx,cy,cz,r = p
  17. errout = 0
  18. # cruse bounds mechanism
  19. if r < 0.3:
  20. errout = (0.3 - r) * 100
  21. r = 0.3
  22. if r > 2.0:
  23. errout = (r - 2.0) * 100
  24. r = 2.0
  25. corr = Vector3(cx,cy,cz)
  26. (baseline_field,baseline_throttle) = data[0]
  27. ret = []
  28. for d in data:
  29. (mag,throttle) = d
  30. cmag = mag + corr * math.pow(throttle,r)
  31. err = (cmag - baseline_field).length()
  32. err += errout
  33. ret.append(err)
  34. return ret
  35. def fit_data(data):
  36. from scipy import optimize
  37. p0 = [0.0, 0.0, 0.0, 1.0]
  38. p1, ier = optimize.leastsq(mag_error, p0[:], args=(data))
  39. if not ier in [1, 2, 3, 4]:
  40. raise RuntimeError("Unable to find solution")
  41. return (Vector3(p1[0], p1[1], p1[2]), p1[3])
  42. def magfit(logfile):
  43. '''find best magnetometer offset fit to a log file'''
  44. print("Processing log %s" % filename)
  45. mlog = mavutil.mavlink_connection(filename)
  46. data = []
  47. throttle = 0
  48. # now gather all the data
  49. while True:
  50. m = mlog.recv_match(condition=args.condition)
  51. if m is None:
  52. break
  53. if m.get_type() == "MAG":
  54. mag = Vector3(m.MagX, m.MagY, m.MagZ)
  55. data.append((mag, throttle))
  56. #if m.get_type() == "RCOU":
  57. # throttle = math.sqrt(m.C1/500.0)
  58. if m.get_type() == "CTUN":
  59. throttle = m.ThO
  60. print("Extracted %u data points" % len(data))
  61. (cmot,r) = fit_data(data)
  62. print("Fit : %s r: %s" % (cmot,r))
  63. x = range(len(data))
  64. errors = mag_error((cmot.x,cmot.y,cmot.z,r), data)
  65. import matplotlib.pyplot as plt
  66. plt.plot(x, errors, 'bo-')
  67. x1,x2,y1,y2 = plt.axis()
  68. plt.axis((x1,x2,0,y2))
  69. plt.ylabel('Error')
  70. plt.xlabel('Sample')
  71. plt.show()
  72. for filename in args.logs:
  73. magfit(filename)