RM赛事C型板九轴IMU解算(2)(PID控制温度解决温漂)
摘要:本文介绍了IMU传感器中的热噪声问题及其导致的零漂现象。热噪声由电子热运动产生,会引起IMU数据偏移,表现为静止状态下仍有输出值。解决方法包括测量零漂值并进行补偿,但需保持温度恒定以确保零漂值稳定。文中详细讲解了基于STM32和PID控制的温度调节方案,包括CubeMX配置、代码移植和PID参数设置。通过控制IMU工作温度,可有效减小热噪声带来的测量误差。该方案适用于非FreeRTOS环境,
传感器的基本功能便是把外界不同的物理量,化学量和生物量变换容易处理的电信号或者数字信号并输出。 而由于实际上传感器中在放大,滤波,采样等过程不可避免地引入噪声,其中一个重要的噪声便是热噪声。热噪声是指由于电子热运动产生的随机电信号,热噪声导致 IMU 数据偏移是 IMU 会产生零漂现象的重要原因之一。
零漂现象是指当物理量输入为零, 传感器测量的输出量不为零的现象。即 IMU 没有任何运动,陀螺仪和加速度计也会读取到一定大小的数据,并将其当作是由 IMU 运动产生的。因此需要在 IMU 上电时首先测量出零漂的大小,将 IMU 测量到的值与零漂值相减,从而减少零漂的影响。这种方法的前提是 IMU 的零漂值保持固定,否则依然会引入误差。
热噪声的幅度和温度成正相关,所以零漂值受到温度的影响,因此需要控制 IMU 的温度保持一个恒定的范围内,从而减少零漂带来的影响。
但是比较尴尬的是c板里只能做温度低于基准后做升温处理,如果温度过高,只能自行散热
关于PID的知识可以看我前面的文章,这里不在赘述。
然后想和大家说的是大疆写着篇程序是使用的是FreeRTOS系统下写的,如果没学确实不太能看懂,也挺麻烦,所以我下面讲的就是把大疆的主要控制程序全部拆解出来,让大家即使不会FreeRTOS也能使用,如果想加上FreeRTOS也很简单自己移植就可以了
下面直接讲配置,CubeMX的配置和上一张的BMI088大差不差,要加一点东西
但是要开启定时器10PIM的通道1,切记要用PF6作为通道,


然后建立程序就行了,
然后打开文件


把这三个文件的所有文件都放打你自己的工程里去
打开你自己建立的CubeMX工程,找到Core并打开
.c 文件在Src .h文件放到Inc中
然后在MdkARM中打开Keil

大致步骤像这样创立一个自己的文件夹,并在里面加入这些文件
有些同学可能找不到刚刚放进去的文件,由于添加文件只会默认打开本层目录但是我们的文件刚刚防,但是我们刚刚帮文件都放到了上层目录下的Core文件中,所以要回到上层都Core文件里找,
创建好之后打开
#include "imu_temp_control_task.c"
文件
把这些头文件复制到你自己的main.c中去
#include "imu_temp_control_task.h"
#include "BMI088driver.h"
#include "pid.h"
#include "bsp_imu_pwm.h"
然后复制或定义这些宏和变量
#define IMU_temp_PWM(pwm) imu_pwm_set(pwm) //pwm����
#define TEMPERATURE_PID_KP 1600.0f //kp of temperature control PID
#define TEMPERATURE_PID_KI 0.2f //ki of temperature control PID
#define TEMPERATURE_PID_KD 0.0f //kd of temperature control PID
#define TEMPERATURE_PID_MAX_OUT 4500.0f //max out of temperature control PID
#define TEMPERATURE_PID_MAX_IOUT 4400.0f //max iout of temperature control PID
extern SPI_HandleTypeDef hspi1;
volatile uint8_t imu_start_flag = 0;
uint16_t tempPWM;
fp32 gyro[3], accel[3], temp;
//kp, ki,kd three params
const fp32 imu_temp_PID[3] = {TEMPERATURE_PID_KP, TEMPERATURE_PID_KI, TEMPERATURE_PID_KD};
//pid struct
pid_type_def imu_temp_pid;
然后为了方便,打开main.h文件添加这些东西
#define CS1_ACCEL_GPIO_Port GPIOA
#define CS1_ACCEL_Pin GPIO_PIN_4
#define CS1_GYRO_GPIO_Port GPIOB
#define CS1_GYRO_Pin GPIO_PIN_0
"struct_typedef.h"
本来前面没用到
"struct_typedef.h"头文件,但是改太多定义有点麻烦,现在感觉香
然后下一步,可能会由于CubeMX的版本不同情况不一样,有的版本在开启后会自动打开PWM但是有的不行,但是重复开启也没啥大问题
HAL_TIM_PWM_Start(&htim10,TIM_CHANNEL_1);
然后再复制这些
PID_init(&imu_temp_pid, PID_POSITION, imu_temp_PID, TEMPERATURE_PID_MAX_OUT, TEMPERATURE_PID_MAX_IOUT);
while(BMI088_init())
{
;
}
//set spi frequency
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
然后再
while(1)中添加这些
BMI088_read(gyro, accel, &temp);
PID_calc(&imu_temp_pid, temp, 40.0f);
if (imu_temp_pid.out < 0.0f)
{
imu_temp_pid.out = 0.0f;
}
tempPWM = (uint16_t)imu_temp_pid.out;
IMU_temp_PWM(tempPWM);
最后的最后,由于我们不用FreeRTOS,所以直接把
#include "imu_temp_control_task.c"
这个文件里面的内容全部注释掉就可了
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)