4 fit best estimate of magnetometer offsets 6 from __future__
import print_function
7 from builtins
import range
9 from argparse
import ArgumentParser
10 parser = ArgumentParser(description=__doc__)
11 parser.add_argument(
"--no-timestamps", dest=
"notimestamps", action=
'store_true', help=
"Log doesn't have timestamps")
12 parser.add_argument(
"--condition", default=
None, help=
"select packets by condition")
13 parser.add_argument(
"--noise", type=float, default=0, help=
"noise to add")
14 parser.add_argument(
"--mag2", action=
'store_true', help=
"use 2nd mag from DF log")
15 parser.add_argument(
"--radius", default=
None, type=float, help=
"target radius")
16 parser.add_argument(
"--plot", action=
'store_true', help=
"plot points in 3D")
17 parser.add_argument(
"logs", metavar=
"LOG", nargs=
"+")
19 args = parser.parse_args()
21 from pymavlink
import mavutil
27 from random
import gauss
28 v =
Vector3(gauss(0, 1), gauss(0, 1), gauss(0, 1))
37 key =
"%u:%u:%u" % (mag.x/20,mag.y/20,mag.z/20)
44 print(len(data), len(ret))
48 '''return radius give data point and offsets''' 49 return (mag + offsets).length()
52 '''return +1 or -1 for for sorting''' 62 if args.radius
is not None:
73 from scipy
import optimize
75 p0 = [0.0, 0.0, 0.0, 0.0]
76 p1, ier = optimize.leastsq(sphere_error, p0[:], args=(data))
77 if not ier
in [1, 2, 3, 4]:
78 raise RuntimeError(
"Unable to find solution")
79 if args.radius
is not None:
83 return (
Vector3(p1[0], p1[1], p1[2]), r)
86 '''find best magnetometer offset fit to a log file''' 88 print(
"Processing log %s" % filename)
89 mlog = mavutil.mavlink_connection(filename, notimestamps=args.notimestamps)
98 m = mlog.recv_match(condition=args.condition)
101 if m.get_type() ==
"SENSOR_OFFSETS":
103 offsets =
Vector3(m.mag_ofs_x, m.mag_ofs_y, m.mag_ofs_z)
104 if m.get_type() ==
"RAW_IMU":
105 mag =
Vector3(m.xmag, m.ymag, m.zmag)
107 data.append(mag - offsets +
noise())
108 if m.get_type() ==
"MAG" and not args.mag2:
109 offsets =
Vector3(m.OfsX,m.OfsY,m.OfsZ)
110 mag =
Vector3(m.MagX,m.MagY,m.MagZ)
111 data.append(mag - offsets +
noise())
112 if m.get_type() ==
"MAG2" and args.mag2:
113 offsets =
Vector3(m.OfsX,m.OfsY,m.OfsZ)
114 mag =
Vector3(m.MagX,m.MagY,m.MagZ)
115 data.append(mag - offsets +
noise())
117 print(
"Extracted %u data points" % len(data))
118 print(
"Current offsets: %s" % offsets)
125 data.sort(
lambda a,b :
radius_cmp(a,b,offsets))
126 data = data[len(data)/16:-len(data)/16]
129 (offsets, field_strength) =
fit_data(data)
131 for count
in range(3):
133 data.sort(
lambda a,b :
radius_cmp(a,b,offsets))
135 print(
"Fit %u : %s field_strength=%6.1f to %6.1f" % (
140 data = data[len(data)/8:-len(data)/8]
143 (offsets, field_strength) =
fit_data(data)
145 print(
"Final : %s field_strength=%6.1f to %6.1f" % (
153 '''plot data in 3D''' 154 import matplotlib.pyplot
as plt
156 for dd, c
in [(orig_data,
'r'), (data, 'b')]:
158 ax = fig.add_subplot(111, projection=
'3d')
160 xs = [ d.x
for d
in dd ]
161 ys = [ d.y
for d
in dd ]
162 zs = [ d.z
for d
in dd ]
163 ax.scatter(xs, ys, zs, c=c, marker=
'o')
165 ax.set_xlabel(
'X Label')
166 ax.set_ylabel(
'Y Label')
167 ax.set_zlabel(
'Z Label')
171 for filename
in args.logs: