Files
tronone-h7-scaffold/User_Code/module/algorithm/controller/ffc/ffc.c

105 lines
3.5 KiB
C
Raw Normal View History

2026-02-12 00:41:34 +08:00
#include "ffc.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
// 内部使用的辅助函数:重置句柄
static void FFC_ResetInstance(FFC_Handle_t *handle) {
// 将整个结构体清零,相当于 C++ 的值初始化
memset(handle, 0, sizeof(FFC_Handle_t));
}
float FFC_FeedForwardCalc(FFC_Handle_t *handle, float target) {
if (handle == NULL) return 0.0f;
// 获取时间间隔 dt
handle->dt = DWT_GetDeltaT(&handle->DWT_CNT);
// 设置当前目标值
handle->set[FFC_NOW] = target;
// 低通滤波处理 (完全保留原代码逻辑)
// 注意:数学上 transform: x = x * dt/(LPF+dt) + x * LPF/(LPF+dt) 等同于 x = x。
// 这里保留原代码逻辑以防有特殊 side effect 需求。
float denominator = handle->configs.FFC_LPF + handle->dt;
if (denominator != 0.0f) {
handle->set[FFC_NOW] = handle->set[FFC_NOW] * handle->dt / denominator +
handle->set[FFC_NOW] * handle->configs.FFC_LPF / denominator;
}
// 前馈计算: Proportional + Derivative + Acceleration
// result = c1*x + c2*v + c3*a
float p_term = handle->configs.c1 * handle->set[FFC_NOW];
float d_term = 0.0f;
float a_term = 0.0f;
if (handle->dt > 0.000001f) { // 防止除以零
d_term = handle->configs.c2 * (handle->set[FFC_NOW] - handle->set[FFC_LAST]) / handle->dt;
a_term = handle->configs.c3 * (handle->set[FFC_NOW] - 2 * handle->set[FFC_LAST] + handle->set[FFC_LLAST]) / (handle->dt * handle->dt);
}
handle->result = p_term + d_term + a_term;
// 限幅
handle->result = abs_clip(handle->result, handle->configs.MaxOutput);
// 更新历史状态
2026-02-12 01:12:05 +08:00
// 注意:原代码中先更新 LAST 再更新 LLAST这会导致移位寄存器逻辑变为 LLAST = (新的)LAST。
2026-02-12 00:41:34 +08:00
// 为了保持转换的一致性,这里保留原代码的顺序。
handle->set[FFC_LAST] = handle->set[FFC_NOW];
handle->set[FFC_LLAST] = handle->set[FFC_LAST];
return handle->result;
}
void FFC_SetConfig(FFC_Handle_t *handle, FFC_Init_Config_s config) {
if (handle == NULL) return;
// 使用值初始化清除 ffc_s 对象
FFC_ResetInstance(handle);
// 复制配置参数
handle->configs = config;
}
void FFC_CheckPointer(FFC_Handle_t *handle, float *get) {
if (handle == NULL) return;
handle->get_data = get;
}
void FFC_Init(FFC_Handle_t *handle, FFC_Init_Config_s config, float *get) {
if (handle == NULL) return;
FFC_SetConfig(handle, config);
if (get != NULL) {
FFC_CheckPointer(handle, get);
}
}
float FFC_Handle(FFC_Handle_t *handle, float target) {
return FFC_FeedForwardCalc(handle, target);
}
void FFC_DebugControl(FFC_Handle_t *handle, float *imu_data, float *data_from_gimbalctrl_yaw) {
if (handle == NULL || imu_data == NULL || data_from_gimbalctrl_yaw == NULL) return;
handle->debug.count++;
handle->debug.total_imu_yaw = *imu_data;
// 生成正弦波目标值
handle->debug.target = (float)(sin(handle->debug.count * 0.003) * 1.0);
// 输出到 gimbal ctrl
*data_from_gimbalctrl_yaw = handle->debug.target;
// 逻辑判断
if (fabsf(*data_from_gimbalctrl_yaw) < 0.01f && handle->debug.if_gimbal_ctrl == 0) {
handle->debug.if_gimbal_ctrl = 1; // true
DWT_GetDeltaT(&handle->debug.DWT_CNT);
}
if (handle->debug.if_gimbal_ctrl == 1 && fabsf(*imu_data) < 0.01f) {
handle->debug.if_gimbal_ctrl = 0; // false
handle->debug.error = DWT_GetDeltaT(&handle->debug.DWT_CNT);
}
}