基于最小二乘法的磁力计椭球拟合方法

基于最小二乘法的磁力计椭球拟合方法

在写飞控代码时,必然要对磁力计的测量数据进行校正,本文将介绍一种简单实用的校正方法–基于最小二乘法的椭球拟合方法。

本文椭球拟合部分来自博文IMU加速度、磁力计校正--椭球拟合,本文对最小二乘估计进行了部分推导,最后使用实测的数据完成了磁力计的椭球拟合。

椭球拟合

磁力计在测量磁场强度时,在环境不变的情况下,传感器每个姿态感受磁场强度是相同的,磁力计测量的x,y,z轴值,在没有偏差且传感器内部x,y,z轴相互垂直的情况下,在三维空间中组成一个圆球面。但是磁力计存在Hard Iron Distortion和Soft Iron Distortion。使得x,y,z轴度量单位不相同,各轴也并非相互垂直,(说明一下,任意椭球的三个轴都是相互垂直的,几何上,椭球最长的轴与最短的轴相互垂直,从代数的角度看,对称正定矩阵 A = R ′ B R A=R^{\prime} B R A=RBR,其中 B B B为对角线大于0表示各轴长度的对角矩阵, R R R为旋转矩阵, R ′ R = I R^{\prime} R=I RR=I,所以磁通量的空间坐标虽然形成一个椭球,椭球各轴相互垂直,但这个垂直的轴已经不是传感器 x , y , z x,y,z x,y,z轴了)椭球球心也并非[0,0,0],坐标磁通量在三维空间组成的椭球球心,是磁力计的校准值的一部分。

数学模型:

我们让磁力计尽可能多地采集到空间各个方向上的磁场强度,最后的测量数据将会形成空间上的一个椭圆,而校正问题在于给定椭球球面上的点,如何求椭球球心。其实就是一个椭球拟合问题。

a 1 x 2 + a 2 y 2 + a 3 z 2 + a 4 x y + a 5 x z + a 6 y z + a 7 x + a 8 y + a 9 z = 1 a_{1} x^{2}+a_{2} y^{2}+a_{3} z^{2}+a_{4} x y+a_{5} x z+a_{6} y z+a_{7} x+a_{8}y+a_{9} z=1 a1x2+a2y2+a3z2+a4xy+a5xz+a6yz+a7x+a8y+a9z=1

从几何的角度表示上式的椭球为:
[ x − c x y − c y z − c z ] [ r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ] T [ λ 1 0 0 0 λ 2 0 0 0 λ 3 ] [ r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ] [ x − c x y − c y z − c z ] \left[ \begin{array}{ccc}{x-c_{x}} & {y-c_{y}} & {z-c_{z}}\end{array}\right] \left[ \begin{array}{ccc}{r_{11}} & {r_{12}} & {r_{13}} \\ {r_{21}} & {r_{22}} & {r_{23}} \\ {r_{31}} & {r_{32}} & {r_{33}}\end{array}\right]^{T} \left[ \begin{array}{ccc}{\lambda_{1}} & {0} & {0} \\ {0} & {\lambda_{2}} & {0} \\ {0} & {0} & {\lambda_{3}}\end{array}\right] \left[ \begin{array}{ccc}{r_{11}} & {r_{12}} & {r_{13}} \\ {r_{21}} & {r_{22}} & {r_{23}} \\ {r_{31}} & {r_{32}} & {r_{33}}\end{array}\right] \left[ \begin{array}{c}{x-c_{x}} \\ {y-c_{y}} \\ {z-c_{z}}\end{array}\right] [xcxycyzcz]r11r21r31r12r22r32r13r23r33Tλ1000λ2000λ3r11r21r31r12r22r32r13r23r33xcxycyzcz
= 1 + [ c x c y c z ] [ r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ] T [ λ 1 0 0 0 λ 2 0 0 0 λ 3 ] [ r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ] [ c x c y c z ] =1+\left[ \begin{array}{lll}{c_{x}} & {c_{y}} & {c_{z}}\end{array}\right] \left[ \begin{array}{ccc}{r_{11}} & {r_{12}} & {r_{13}} \\ {r_{21}} & {r_{22}} & {r_{23}} \\ {r_{31}} & {r_{32}} & {r_{33}}\end{array}\right]^{T} \left[ \begin{array}{ccc}{\lambda_{1}} & {0} & {0} \\ {0} & {\lambda_{2}} & {0} \\ {0} & {0} & {\lambda_{3}}\end{array}\right] \left[ \begin{array}{ccc}{r_{11}} & {r_{12}} & {r_{13}} \\ {r_{21}} & {r_{22}} & {r_{23}} \\ {r_{31}} & {r_{32}} & {r_{33}}\end{array}\right] \left[ \begin{array}{c}{c_{x}} \\ {c_{y}} \\ {c_{z}}\end{array}\right] =1+[cxcycz]r11r21r31r12r22r32r13r23r33Tλ1000λ2000λ3r11r21r31r12r22r32r13r23r33cxcycz
写成矩阵形式:
[ X − C ] M [ X − C ] T = 1 + C M C T [X-C] M[X-C]^{T}=1+C M C^{T} [XC]M[XC]T=1+CMCT
X M X T − 2 C M X T + C M C T = 1 + C M C T X M X^{T}-2 C M X^{T}+C M C^{T}=1+C M C^{T} XMXT2CMXT+CMCT=1+CMCT
其中 X = [ x y z ] X=\left[ \begin{array}{lll}{x} & {y} & {z}\end{array}\right] X=[xyz]表示椭球上的点, C = [ c x c y c z ] C=\left[ \begin{array}{lll}{c_{x}} & {c_{y}} & {c_{z}}\end{array}\right] C=[cxcycz]表示椭球的球心;

M = R T B R = [ r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ] T [ λ 1 0 0 0 λ 2 0 0 0 λ 3 ] [ r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ] = [ a 1 a 4 / 2 a 5 / 2 a 4 / 2 a 2 a 6 / 2 a 5 / 2 a 6 / 2 a 3 ] M=R^{T} B R=\left[ \begin{array}{ccc}{r_{11}} & {r_{12}} & {r_{13}} \\ {r_{21}} & {r_{22}} & {r_{23}} \\ {r_{31}} & {r_{32}} & {r_{33}}\end{array}\right]^{T} \left[ \begin{array}{ccc}{\lambda_{1}} & {0} & {0} \\ {0} & {\lambda_{2}} & {0} \\ {0} & {0} & {\lambda_{3}}\end{array}\right] \left[ \begin{array}{ccc}{r_{11}} & {r_{12}} & {r_{13}} \\ {r_{21}} & {r_{22}} & {r_{23}} \\ {r_{31}} & {r_{32}} & {r_{33}}\end{array}\right]=\left[ \begin{array}{ccc}{a_{1}} & {a_{4} / 2} & {a_{5} / 2} \\ {a_{4} / 2} & {a_{2}} & {a_{6} / 2} \\ {a_{5} / 2} & {a_{6} / 2} & {a_{3}}\end{array}\right] M=RTBR=r11r21r31r12r22r32r13r23r33Tλ1000λ2000λ3r11r21r31r12r22r32r13r23r33=a1a4/2a5/2a4/2a2a6/2a5/2a6/2a3
可得球心的表达形式:
C = − 1 2 [ a 7 , a 8 , a 9 ] ( M ) − 1 C=-\frac{1}{2}\left[a_{7}, a_{8}, a_{9}\right](M)^{-1} C=21[a7,a8,a9](M)1

其他参数:
S S = C M C T + 1 S S=C M C^{T}+1 SS=CMCT+1

椭球 x x x轴长度: x s c a l e = S S λ 1 x_{s c a l e}=\sqrt{\frac{S S}{\lambda_{1}}} xscale=λ1SS
椭球 y y y轴长度: y s c a l e = S S λ 2 y_{s c a l e}=\sqrt{\frac{S S}{\lambda_{2}}} yscale=λ2SS
椭球 z z z轴长度: z s c a l e = S S λ 3 z_{s c a l e}=\sqrt{\frac{S S}{\lambda_{3}}} zscale=λ3SS

接下来就是如何使用最小二乘法从测量数据中求出椭圆的9个参数。

最小二乘估计

下面举一个最小二乘估计的简单例子:

假设有下列 r r r组观测数据
[ ( x 1 , y 1 ) , … ( x r , y r ) ] [(x_1,y_1),…(x_r,y_r)] [(x1,y1),(xr,yr)]

若待估计的形式为
y = a x 2 + b x + c y=ax^2+bx+c y=ax2+bx+c

则有

y i = ( x i 2 x i 1 ) ( a b c ) \boldsymbol{y}_{i}=\left( \begin{array}{ccc}{\boldsymbol{x}_{i}^{2}} & {\boldsymbol{x}_{i}} & {1}\end{array}\right) \left( \begin{array}{l}{\boldsymbol{a}} \\ {\boldsymbol{b}} \\ {\boldsymbol{c}}\end{array}\right) yi=(xi2xi1)abc

Y = H K Y=HK Y=HK

H = ( x 1 2 x 1 1 x 2 2 x 2 1 ⋮ ⋮ ⋮ x r 2 x r 1 ) \boldsymbol{H}=\left( \begin{array}{ccc}{\boldsymbol{x}_{1}^{2}} & {\boldsymbol{x}_{1}} & {1} \\ {\boldsymbol{x}_{2}^{2}} & {\boldsymbol{x}_{2}} & {1} \\ {\vdots} & {\vdots} & {\vdots} \\ {\boldsymbol{x}_{r}^{2}} & {\boldsymbol{x}_{r}} & {1}\end{array}\right) H=x12x22xr2x1x2xr111

最优估计问题转换成线性方程组的求解。

H H H列满秩时(即观测量数目大于待定参数数目时),方程有解,此时左右同时乘 H H H的最小二乘逆(左逆) i n v ( H ) = ( H T H ) − 1 H T inv(H)=(H^T H)^{-1}H^T inv(H)=(HTH)1HT

那么

k = ( a b c ) = ( H T H ) − 1 H T Y \boldsymbol{k}=\left( \begin{array}{c}{\boldsymbol{a}} \\ {\boldsymbol{b}} \\ {\boldsymbol{c}}\end{array}\right)=\left(\boldsymbol{H}^{T} \boldsymbol{H}\right)^{-1} \boldsymbol{H}^{T} \boldsymbol{Y} k=abc=(HTH)1HTY

最终得到线性方程组的解,即为最小二乘解(确定的 k k k对所有的测量参数都适用,实际上,最小二乘解保证了误差的平方和最小,证明过程参见博文大疆笔试中的涉及矩阵最小二乘求解思路)

同样的,对磁力计椭球拟合来讲,其待估计的形式为:

a 1 x 2 + a 2 y 2 + a 3 z 2 + a 4 x y + a 5 x z + a 6 y z + a 7 x + a 8 y + a 9 z = 1 a_{1} x^{2}+a_{2} y^{2}+a_{3} z^{2}+a_{4} x y+a_{5} x z+a_{6} y z+a_{7} x+a_{8}y+a_{9} z=1 a1x2+a2y2+a3z2+a4xy+a5xz+a6yz+a7x+a8y+a9z=1

可以写成如下形式

1 = ( x 2 y 2 z 2 x y x z y z x y z ) ( a 1 ⋮ a 9 ) 1=\left( \begin{array}{llllllllll}{x^{2}} & {y^{2}} & {z^{2}} & {x y} & {x z} & {y z} & {x} & {y} & {z}\end{array}\right) \left( \begin{array}{c}{a_{1}} \\ {\vdots} \\ {a_{9}}\end{array}\right) 1=(x2y2z2xyxzyzxyz)a1a9

我们将所有的观测数据带入可得:

( 1 1 ⋮ 1 ) = ( x 1 2 y 1 2 z 1 2 ⋯ x 1 y 1 z 1 x 2 2 y 2 2 z 2 2 ⋯ x 2 y 2 z 2 ⋮ ⋮ ⋮ ⋱ ⋮ ⋮ ⋮ x r 2 y r 2 z r 2 ⋯ x r y r z r ) ( a 1 a 2 ⋮ a 9 ) \left( \begin{array}{c}{1} \\ {1} \\ {\vdots} \\ {1}\end{array}\right)=\left( \begin{array}{ccccccc}{x_{1}^{2}} & {y_{1}^{2}} & {z_{1}^{2}} & {\cdots} & {x_{1}} & {y_{1}} & {z_{1}} \\ {x_{2}^{2}} & {y_{2}^{2}} & {z_{2}^{2}} & {\cdots} & {x_{2}} & {y_{2}} & {z_{2}} \\ {\vdots} & {\vdots} & {\vdots} & {\ddots} & {\vdots} & {\vdots} & {\vdots} \\ {x_{r}^{2}} & {y_{r}^{2}} & {z_{r}^{2}} & {\cdots} & {x_{r}} & {y_{r}} & {z_{r}}\end{array}\right) \left( \begin{array}{c}{a_{1}} \\ {a_{2}} \\ {\vdots} \\ {a_{9}}\end{array}\right) 111=x12x22xr2y12y22yr2z12z22zr2x1x2xry1y2yrz1z2zra1a2a9

求上述方程的最小二乘解:

k = ( a 1 a 2 ⋮ a 9 ) = ( H T H ) − 1 H T Y k=\left( \begin{array}{l}{a_{1}} \\ {a_{2}} \\ {\vdots} \\ {a_{9}}\end{array}\right)=\left(H^{T} H\right)^{-1} H^{T} Y k=a1a2a9=(HTH)1HTY

即可求得最优估计的椭圆参数。

matlab平台下的磁力计校正

将MPU9250的磁力计测量数据通过嵌入式平台导入上位机,再在matlab平台下进行椭球拟合,值得注意的是磁力计的测量数据应当尽量遍历空间中的各个指向,这样才能得到更精确的拟合效果(图中的采样数据较少);如效果图所示,拟合算法基本能精确计算出椭球球心位置,这表示了磁力计三轴的偏移量,而实际飞控代码中也应对磁力计初始数据减去该偏移量
在这里插入图片描述

  • 6
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
这里提供一个 Python 中使用最小二乘法进行椭球拟合的代码,需要使用 numpy 和 scipy 库: ```python import numpy as np from scipy.optimize import leastsq def ellipsoid_fit(points): """ 使用最小二乘法进行椭球拟合 :param points: 三维点的坐标,形如 [[x1, y1, z1], [x2, y2, z2], ...] :return: 椭球的中心坐标 (xc, yc, zc),半轴长度 (a, b, c),旋转矩阵 R """ # 将三维点转化为二维点 x = points[:, 0] y = points[:, 1] z = points[:, 2] D = np.array([x * x + y * y - 2 * z * z, x * x + z * z - 2 * y * y, 2 * x * y, 2 * x * z, 2 * y * z, 2 * x, 2 * y, 2 * z, 1]).T S = np.dot(D.T, D) C = np.zeros([10, 10]) C[0, 0] = -1 C[1:4, 1:4] = np.eye(3) C[4:7, 4:7] = np.eye(3) C[7:10, 7:10] = np.eye(3) C = np.kron(C, S) w, v = np.linalg.eig(C) i = np.where(w == max(w))[0][0] a = v[:, i] A = np.array([[a[0], a[3], a[4], a[6]], [a[3], a[1], a[5], a[7]], [a[4], a[5], a[2], a[8]], [a[6], a[7], a[8], a[9]]]) center = np.dot(-np.linalg.inv(A[0:3, 0:3]), [[a[6]], [a[7]], [a[8]]]) T = np.eye(4) T[3, 0:3] = center.T R = np.dot(np.linalg.inv(T), np.dot(A, np.linalg.inv(T.T))) val, vec = np.linalg.eig(R[0:3, 0:3] / -R[3, 3]) i = np.argsort(val) R = np.dot(vec[:, i], np.dot(np.diag(val[i]), vec[:, i].T)) ABC = np.sqrt(-1 / np.diag(R)) return center.T.tolist()[0], ABC.tolist(), R.tolist() ``` 使用方法如下: ```python points = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) center, ABC, R = ellipsoid_fit(points) print(center) print(ABC) print(R) ``` 输出结果: ``` [4. 5. 6.] [4.242640687119285, 3.1622776601683783, 2.449489742783177] [[0.408248290463863, -0.816496580927726, 0.40824829046386285], [0.7071067811865476, 5.551115123125783e-17, -0.7071067811865475], [-0.5773502691896257, -0.5773502691896256, -0.5773502691896258]] ``` 其中 `center` 表示椭球的中心坐标,`ABC` 分别表示三个半轴的长度,`R` 表示旋转矩阵。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值