Files
FDR-Core/Core/Src/ladrc.c
2026-03-08 18:17:14 +08:00

109 lines
3.0 KiB
C
Raw 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.
#include "ladrc.h"
/**
* @brief 初始化单体 LADRC 参数
*/
void LADRC_Init(LADRC_TypeDef *ladrc, float wc, float wo, float b0, float h, float max) {
// 状态初始化
ladrc->v = 0.0f;
ladrc->y = 0.0f;
ladrc->z1 = 0.0f;
ladrc->z2 = 0.0f;
ladrc->u = 0.0f;
// 参数赋值
ladrc->wc = wc;
ladrc->wo = wo;
ladrc->b0 = b0;
ladrc->h = h;
ladrc->out_max = max;
// 计算观测器增益
ladrc->beta1 = 2.0f * wo;
ladrc->beta2 = wo * wo;
}
/**
* @brief 单体 LADRC 核心运算
*/
float LADRC_Calc(LADRC_TypeDef *ladrc, float actual_val) {
ladrc->y = actual_val;
// 第一部分LESO
float e = ladrc->y - ladrc->z1;
ladrc->z1 += (ladrc->z2 + ladrc->b0 * ladrc->u + ladrc->beta1 * e) * ladrc->h;
ladrc->z2 += (ladrc->beta2 * e) * ladrc->h;
// 第二部分LSEF & 扰动补偿
float u0 = ladrc->wc * (ladrc->v - ladrc->z1);
float out = (u0 - ladrc->z2) / ladrc->b0;
// 第三部分:输出限幅保护
if (out > ladrc->out_max) out = ladrc->out_max;
if (out < -ladrc->out_max) out = -ladrc->out_max;
ladrc->u = out;
return out;
}
/* =====================================================================
* 针对四轮底盘的 LADRC 扩展调度层
* ===================================================================== */
// 实例化 4 个控制器的实体
LADRC_TypeDef ladrc_motors[4];
/**
* @brief 一键初始化底层硬件与四个 LADRC
*/
void FourWheel_LADRC_Init(void)
{
// 1. 唤醒底层电机与编码器硬件
Motor_Init();
// 2. 初始化 4 个控制器的参数 (注意这里的限幅是 1000匹配底层的 PWM_LIMIT)
for(int i = 0; i < 4; i++) {
LADRC_Init(&ladrc_motors[i], 25.0f, 60.0f, 0.2f, 0.01f, 1000.0f);
}
}
/**
* @brief 一键下发四个轮子的目标转速
*/
void FourWheel_Set_Target_RPM(float fl_rpm, float rl_rpm, float fr_rpm, float rr_rpm)
{
ladrc_motors[MOTOR_FL].v = fl_rpm;
ladrc_motors[MOTOR_RL].v = rl_rpm;
ladrc_motors[MOTOR_FR].v = fr_rpm;
ladrc_motors[MOTOR_RR].v = rr_rpm;
}
/**
* @brief 四轮闭环大循环 (强烈建议放在 10ms 的定时器中断内执行)
*/
void FourWheel_LADRC_Control_Loop(void)
{
Motor_Update_RPM(0.01f);
// 静态数组,用来记住上一次的平滑速度
static float filtered_rpm[4] = {0.0f, 0.0f, 0.0f, 0.0f};
// 滤波系数 alpha (0.0 ~ 1.0)。越小越平滑,越大越敏捷。
// 0.3 的意思是:相信 30% 的最新数据,保留 70% 的历史数据
const float alpha = 0.3f;
for(int i = 0; i < 4; i++)
{
// 1. 拿到底层的原始狂野转速
float raw_rpm = Get_Motor_RPM((Motor_ID_t)i);
// 2. 软件减震器:一阶低通滤波!
filtered_rpm[i] = (1.0f - alpha) * filtered_rpm[i] + alpha * raw_rpm;
// 3. 把过滤掉毛刺、极其顺滑的速度扔给 LADRC
float pwm_out = LADRC_Calc(&ladrc_motors[i], filtered_rpm[i]);
Set_Motor_Output((Motor_ID_t)i, (int16_t)pwm_out);
}
}