|
【KW41Z】FXOS8700CQ (3D加速度计+3D磁力计) 融合算法
[复制链接]
【KW41Z】FXOS8700CQ (3D加速度计+3D磁力计)
https://bbs.eeworld.com.cn/forum ... 1318&fromuid=194541
(出处: 电子工程世界-论坛)
有一定的认识,这里主要是讲解融合算法
欧拉角是存在万向锁的问题,所以引入了Roll Pitch Yaw ,其相关的定义如下:
再看芯片
刚好是一个方向的,所以不用取反。
对应的推导结果公式如下:
Roll :
Pitch :
.
Yaw:
相关代码
- /* Read sensor data */
- Sensor_ReadData(&g_Ax_Raw, &g_Ay_Raw, &g_Az_Raw, &g_Mx_Raw, &g_My_Raw, &g_Mz_Raw);
- /* Average accel value */
- for (i = 1; i < MAX_ACCEL_AVG_COUNT; i++)
- { //缓冲区
- g_Ax_buff[i] = g_Ax_buff[i - 1];
- g_Ay_buff[i] = g_Ay_buff[i - 1];
- g_Az_buff[i] = g_Az_buff[i - 1];
- }
- g_Ax_buff[0] = g_Ax_Raw; //最新的数据
- g_Ay_buff[0] = g_Ay_Raw;
- g_Az_buff[0] = g_Az_Raw;
- for (i = 0; i < MAX_ACCEL_AVG_COUNT; i++) //求平均值
- {
- g_Ax += (double)g_Ax_buff[i];
- g_Ay += (double)g_Ay_buff[i];
- g_Az += (double)g_Az_buff[i];
- }
- g_Ax /= MAX_ACCEL_AVG_COUNT;
- g_Ay /= MAX_ACCEL_AVG_COUNT;
- g_Az /= MAX_ACCEL_AVG_COUNT;
- if(g_FirstRun)
- {
- g_Mx_LP = g_Mx_Raw;
- g_My_LP = g_My_Raw;
- g_Mz_LP = g_Mz_Raw;
- }
- g_Mx_LP += ((double)g_Mx_Raw - g_Mx_LP) * 0.01; //低通滤波
- g_My_LP += ((double)g_My_Raw - g_My_LP) * 0.01;
- g_Mz_LP += ((double)g_Mz_Raw - g_Mz_LP) * 0.01;
- /* Calculate magnetometer values 减去偏差*/
- g_Mx = g_Mx_LP - g_Mx_Offset;
- g_My = g_My_LP - g_My_Offset;
- g_Mz = g_Mz_LP - g_Mz_Offset;
- /* Calculate roll angle g_Roll (-180deg, 180deg) and sin, cos */
- g_Roll = atan2(g_Ay, g_Az) * RadToDeg;
- sinAngle = sin(g_Roll * DegToRad);
- cosAngle = cos(g_Roll * DegToRad);
- /* De-rotate by roll angle g_Roll */
- By = g_My * cosAngle - g_Mz * sinAngle;
- g_Mz = g_Mz * cosAngle + g_My * sinAngle;
- g_Az = g_Ay * sinAngle + g_Az * cosAngle;
- /* Calculate pitch angle g_Pitch (-90deg, 90deg) and sin, cos*/
- g_Pitch = atan2(-g_Ax , g_Az) * RadToDeg;
- sinAngle = sin(g_Pitch * DegToRad);
- cosAngle = cos(g_Pitch * DegToRad);
- /* De-rotate by pitch angle g_Pitch */
- Bx = g_Mx * cosAngle + g_Mz * sinAngle;
- /* Calculate yaw = ecompass angle psi (-180deg, 180deg) */
- g_Yaw = atan2(-By, Bx) * RadToDeg;
- if(g_FirstRun)
- {
- g_Yaw_LP = g_Yaw;
- g_FirstRun = false;
- }
- g_Yaw_LP += (g_Yaw - g_Yaw_LP) * 0.01;//低通滤波
复制代码
|
|