rm_balance/User/task/atti_esit.c
2026-02-04 15:05:04 +08:00

150 lines
4.9 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
atti_esit Task
*/
/* Includes ----------------------------------------------------------------- */
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "bsp/gpio.h"
#include "bsp/mm.h"
#include "bsp/pwm.h"
#include "component/ahrs.h"
#include "component/QuaternionEKF.h"
#include "component/pid.h"
#include "device/bmi088.h"
#include "device/mrobot.h"
#include "device/device.h"
#include "module/balance_chassis.h"
#include "task/user_task.h"
#include <stdio.h>
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
BMI088_t bmi088;
#ifndef USE_QEKF
AHRS_t gimbal_ahrs;
AHRS_Magn_t magn;
#endif
AHRS_Eulr_t eulr_to_send;
Chassis_IMU_t imu_for_chassis;
KPID_t imu_temp_ctrl_pid;
/*默认校准参数*/
BMI088_Cali_t cali_bmi088 = {
.gyro_offset = {-0.00147764047f, -0.00273479894f, 0.00154074503f},
};
static const KPID_Params_t imu_temp_ctrl_pid_param = {
.k = 0.1f,
.p = 0.15f,
.i = 0.01f,
.d = 0.02f,
.i_limit = 1.0f,
.out_limit = 1.0f,
};
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/**
* @brief IMU 设备打印回调函数
*/
static int print_imu_callback(const void *data, char *buffer, size_t size) {
const BMI088_t *imu = (const BMI088_t *)data;
#define RAD2DEG 57.2957795131f
return MRobot_Snprintf(buffer, size,
" Status : %s\r\n"
" Accel : X=%.3f Y=%.3f Z=%.3f (m/s^2)\r\n"
" Gyro : X=%.3f Y=%.3f Z=%.3f (rad/s)\r\n"
" Euler : R=%.2f P=%.2f Y=%.2f (deg)\r\n"
" Temp : %.1f C\r\n",
imu->header.online ? "Online" : "Offline",
imu->accl.x, imu->accl.y, imu->accl.z,
imu->gyro.x, imu->gyro.y, imu->gyro.z,
eulr_to_send.rol * RAD2DEG, eulr_to_send.pit * RAD2DEG, eulr_to_send.yaw * RAD2DEG,
imu->temp);
}
/* Exported functions ------------------------------------------------------- */
void Task_atti_esit(void *argument) {
(void)argument; /* 未使用argument消除警告 */
osDelay(ATTI_ESIT_INIT_DELAY); /* 延时一段时间再开启任务 */
/* USER CODE INIT BEGIN */
BMI088_Init(&bmi088, &cali_bmi088);
#ifdef USE_QEKF
QEKF_Init(10.0f, 0.001f, 1000000.0f, 0.9996f, 0.0f);
#else
AHRS_Init(&gimbal_ahrs, &magn, BMI088_GetUpdateFreq(&bmi088));
#endif
PID_Init(&imu_temp_ctrl_pid, KPID_MODE_NO_D,
1.0f / BMI088_GetUpdateFreq(&bmi088), &imu_temp_ctrl_pid_param);
BSP_PWM_Start(BSP_PWM_IMU_HEAT);
/* 注册 IMU 设备到 MRobot */
MRobot_RegisterDevice("bmi088", &bmi088, print_imu_callback);
/* USER CODE INIT END */
while (1) {
/* USER CODE BEGIN */
BMI088_WaitNew();
BMI088_AcclStartDmaRecv();
BMI088_AcclWaitDmaCplt();
BMI088_GyroStartDmaRecv();
BMI088_GyroWaitDmaCplt();
/* 锁住RTOS内核防止数据解析过程中断造成错误 */
osKernelLock();
/* 接收完所有数据后,把数据从原始字节加工成方便计算的数据 */
BMI088_ParseAccl(&bmi088);
BMI088_ParseGyro(&bmi088);
// IST8310_Parse(&ist8310);
/* 根据设备接收到的数据进行姿态解析 */
#ifdef USE_QEKF
QEKF_Update(bmi088.gyro.x, bmi088.gyro.y, bmi088.gyro.z,
bmi088.accl.x, bmi088.accl.y, bmi088.accl.z,
1.0f / BMI088_GetUpdateFreq(&bmi088));
/* 从EKF获取欧拉角 */
eulr_to_send.rol = QEKF_INS.roll;
eulr_to_send.pit = QEKF_INS.pitch;
eulr_to_send.yaw = QEKF_INS.yaw;
#else
AHRS_Update(&gimbal_ahrs, &bmi088.accl, &bmi088.gyro, &magn);
/* 根据解析出来的四元数计算欧拉角 */
AHRS_GetEulr(&eulr_to_send, &gimbal_ahrs);
#endif
/* 加速度计数据绕z轴旋转270度: (x,y,z) -> (y,-x,z) */
imu_for_chassis.accl.x = bmi088.accl.y;
imu_for_chassis.accl.y = -bmi088.accl.x;
imu_for_chassis.accl.z = bmi088.accl.z;
/* 陀螺仪数据绕z轴旋转270度: (x,y,z) -> (y,-x,z) */
imu_for_chassis.gyro.x = bmi088.gyro.y;
imu_for_chassis.gyro.y = -bmi088.gyro.x;
imu_for_chassis.gyro.z = bmi088.gyro.z;
/* 欧拉角绕z轴旋转270度 */
imu_for_chassis.euler.rol = eulr_to_send.pit;
imu_for_chassis.euler.pit = -eulr_to_send.rol;
imu_for_chassis.euler.yaw = eulr_to_send.yaw - 1.57079632679f; // -90度
osMessageQueueReset(
task_runtime.msgq.chassis.imu); // 重置消息队列,防止阻塞
osMessageQueuePut(task_runtime.msgq.chassis.imu, &imu_for_chassis, 0,
0); // 非阻塞发送底盘IMU数据
BSP_PWM_SetComp(BSP_PWM_IMU_HEAT, PID_Calc(&imu_temp_ctrl_pid, 40.5f,
bmi088.temp, 0.0f, 0.0f));
osKernelUnlock();
/* USER CODE END */
}
}