BetaFlight模块设计之十:磁力计任务分析

BetaFlight模块设计之十:磁力计任务分析

基于BetaFlight开源代码框架简介的框架设计,逐步分析内部模块功能设计。

磁力计任务

描述:磁力计主要根据地球磁场感知方向,这里主要用于获取磁力计传感器数据,并通知相关任务或模块。

 ├──> 初始化
 │   ├──> [v]硬件初始化compassDetect(qmc5883lDetect/qmc5883lInit)/pgResetFn_compassConfig/compassPreInit
 │   └──> [v]业务初始化compassInit
 ├──> 任务
 │   ├──> [x]实时任务
 │   ├──> [x]事件任务
 │   └──> [v]时间任务[TASK_COMPASS] = DEFINE_TASK("COMPASS", NULL, NULL, taskUpdateMag, TASK_PERIOD_HZ(10), TASK_PRIORITY_LOW),
 ├──> 驱动
 │   ├──> [v]查询qmc5883lRead
 │   └──> [x]中断
 └──> 接口
     ├──> bool compassIsHealthy(void)
     └──> bool compassIsCalibrationComplete(void)

taskUpdateMag函数分析

配置SENSOR_MAG就执行更新函数compassUpdate,遇到异常重新规划下次任务执行时间rescheduleTask。

taskUpdateMag
 └──> sensors(SENSOR_MAG)
     ├──> const uint32_t newDeadline = compassUpdate(currentTimeUs);
     └──> <newDeadline != 0>
         └──> rescheduleTask(TASK_SELF, newDeadline);

compassUpdate函数分析

这里有个一30秒以上的FlashWrite操作,理论上来说EEFlash的寿命这种强度下,这种飞控场景失败概率不高可忽略。为什么要做这个保存?

注:这里我们Kakute F7 AIO是具备BlackBox的SD卡硬件功能的。

compassUpdate
 ├──> <busBusy(&magDev.dev, NULL) || !magDev.read(&magDev, magADCRaw)> //总线忙或者读取ADC数据失败
 │   ├──> schedulerIgnoreTaskExecRate
 │   └──> return 1000 // 1ms
 ├──> [更新三轴ADC数据]
 ├──> <ALIGN_CUSTOM>[alignSensorViaMatrix(mag.magADC, &magDev.rotationMatrix);]
 ├──> <magDev.magAlignment, internal>[alignSensorViaRotation(mag.magADC, magDev.magAlignment);]
 ├──> <第一次loop>[赋值初始化,使用compassConfigMutable()->magZero]
 ├──> <已校准>
 │   ├──> <30s以内>
 │   │   ├──> LED0_TOGGLE
 │   │   └──> 最大值最小值更新
 │   └──> <超出30s>
 │       ├──> magZero->raw取最大最小平均值
 │       └──> saveConfigAndNotify
 └──> return TASK_PERIOD_HZ(10);

磁力计配置

注:硬件配置\src\main\target\KAKUTEF7\target.h

#define USE_MAG
#define USE_MAG_HMC5883
#define USE_MAG_QMC5883
#define USE_MAG_LIS3MDL
#define MAG_I2C_INSTANCE      I2C_DEVICE
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是磁力计校准最小二乘椭球拟合的C代码实现: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> #define MAX_POINTS 1000 #define MAX_VARS 10 double X[MAX_POINTS][MAX_VARS], X_T[MAX_VARS][MAX_POINTS], X_T_X[MAX_VARS][MAX_VARS], X_T_Y[MAX_VARS], A[MAX_VARS]; double Y[MAX_POINTS]; int num_points, num_vars; void transpose(double X[][MAX_VARS], int n, int m, double X_T[][MAX_POINTS]) { int i, j; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { X_T[j][i] = X[i][j]; } } } void multiply(double X[][MAX_VARS], int n, int m, double Y[MAX_VARS], double Z[MAX_VARS]) { int i, j; for (i = 0; i < n; i++) { Z[i] = 0.0; for (j = 0; j < m; j++) { Z[i] += X[i][j] * Y[j]; } } } void matrix_multiply(double X[][MAX_VARS], double Y[][MAX_VARS], int n, int m, int p, double Z[][MAX_VARS]) { int i, j, k; for (i = 0; i < n; i++) { for (j = 0; j < p; j++) { Z[i][j] = 0.0; for (k = 0; k < m; k++) { Z[i][j] += X[i][k] * Y[k][j]; } } } } void invert(double X[][MAX_VARS], int n, double Y[][MAX_VARS]) { int i, j, k; double temp; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { Y[i][j] = (i == j) ? 1.0 : 0.0; } } for (k = 0; k < n; k++) { temp = X[k][k]; for (j = 0; j < n; j++) { X[k][j] /= temp; Y[k][j] /= temp; } for (i = k + 1; i < n; i++) { temp = X[i][k]; for (j = 0; j < n; j++) { X[i][j] -= X[k][j] * temp; Y[i][j] -= Y[k][j] * temp; } } } for (k = n - 1; k > 0; k--) { for (i = k - 1; i >= 0; i--) { temp = X[i][k]; for (j = 0; j < n; j++) { X[i][j] -= X[k][j] * temp; Y[i][j] -= Y[k][j] * temp; } } } } void fit_ellipsoid(double X[][MAX_VARS], double Y[MAX_POINTS], int n, int m, double A[MAX_VARS]) { int i, j; double B[MAX_VARS], C[MAX_VARS]; transpose(X, n, m, X_T); matrix_multiply(X_T, X, m, n, m, X_T_X); matrix_multiply(X_T, Y, m, n, 1, X_T_Y); invert(X_T_X, m, B); multiply(B, X_T_Y, m, m, C); for (i = 0; i < m; i++) { A[i] = C[i]; } } int main() { int i, j; printf("Enter number of points: "); scanf("%d", &num_points); printf("Enter number of variables: "); scanf("%d", &num_vars); printf("Enter data:\n"); for (i = 0; i < num_points; i++) { for (j = 0; j < num_vars; j++) { scanf("%lf", &X[i][j]); } scanf("%lf", &Y[i]); } fit_ellipsoid(X, Y, num_points, num_vars, A); printf("Coefficients:\n"); for (i = 0; i < num_vars; i++) { printf("%lf ", A[i]); } printf("\n"); return 0; } ``` 该代码实现了磁力计校准最小二乘椭球拟合的算法,可以通过输入数据来进行拟合并输出拟合结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值