当前位置: 首页 > news >正文

第三次PID状态机

以下是 apply_params 函数的实现步骤和代码示例:


1. 定义参数结构体

在头文件中定义 PID_Params 结构体,包含需要动态调整的 PID 参数:

// ms_hal_photo_sensor.h
typedef struct {
    float Kp;           // 比例系数
    float Ki;           // 积分系数(直接使用 Ki = Kp*T/Ti)
    float Kd;           // 微分系数(直接使用 Kd = Kp*Td/T)
    float T;            // 控制周期(单位:ms)
    float dead_zone;    // 死区阈值
    float max_delta;    // 单次最大输出变化量
    float output_alpha; // 输出平滑系数(0.0~1.0)
} PID_Params;

2. 定义预设参数集

在代码中预设不同场景的参数集合:

// ms_hal_photo_sensor1.c
// 快速跟踪参数(高响应速度)
static const PID_Params fast_params = {
    .Kp = 0.8,
    .Ki = 0.05,
    .Kd = 0.1,
    .T = 20,
    .dead_zone = 10,
    .max_delta = 20,
    .output_alpha = 0.2
};

// 稳态参数(低噪声抑制)
static const PID_Params slow_params = {
    .Kp = 0.3,
    .Ki = 0.01,
    .Kd = 0.05,
    .T = 50,
    .dead_zone = 20,
    .max_delta = 5,
    .output_alpha = 0.5
};

3. 实现 apply_params 函数

编写函数将参数应用到全局 PID 控制结构体:

// ms_hal_photo_sensor1.c
/**
 * @brief 应用新的PID参数集
 * @param params PID参数结构体指针
 */
void apply_params(const PID_Params* params) {
    if (params == NULL) {
        bk_printf("[ERROR] apply_params: NULL pointer!\r\n");
        return;
    }

    // 原子化更新参数(根据具体平台可能需要关中断)
    PID_Str_Val.Kp = params->Kp;
    PID_Str_Val.Ki = params->Ki;
    PID_Str_Val.Kd = params->Kd;
    PID_Str_Val.T = params->T;
    PID_Str_Val.dead_zone = params->dead_zone;
    PID_Str_Val.max_delta = params->max_delta;
    PID_Str_Val.output_alpha = params->output_alpha;

    // 重置误差历史(避免参数突变导致震荡)
    PID_Str_Val.En = 0;
    PID_Str_Val.En_1 = 0;
    PID_Str_Val.En_2 = 0;

    bk_printf("PID Params Updated: Kp=%.2f Ki=%.2f Kd=%.2f T=%.0fms\r\n", 
             params->Kp, params->Ki, params->Kd, params->T);
}

4. 状态机集成

在定时器回调或控制循环中根据系统状态切换参数:

// ms_hal_photo_sensor1.c
typedef enum {
    PID_STATE_STEADY,     // 稳态
    PID_STATE_TRACKING    // 快速跟踪
} PID_State;

static PID_State current_state = PID_STATE_STEADY;

void photo_timer_handler(void) {
    // ...原有代码...

    // 动态切换参数逻辑
    static uint32_t error_integral = 0;
    error_integral += fabs(PID_Str_Val.En);

    // 每100ms评估一次状态
    static uint8_t eval_counter = 0;
    if (++eval_counter >= 5) { 
        eval_counter = 0;
        
        if (error_integral > 1000) {  // 累计误差大,进入跟踪模式
            if (current_state != PID_STATE_TRACKING) {
                apply_params(&fast_params);
                current_state = PID_STATE_TRACKING;
            }
        } else {                      // 误差小,进入稳态模式
            if (current_state != PID_STATE_STEADY) {
                apply_params(&slow_params);
                current_state = PID_STATE_STEADY;
            }
        }
        error_integral = 0;  // 重置累计误差
    }
}

5. 关键点说明

  1. 原子化操作
    在实时系统中,更新 PID 参数时可能需要关闭中断,确保参数赋值操作的完整性。

  2. 状态切换逻辑
    示例中通过累计误差判断系统状态,实际可根据需求使用其他指标(如误差变化率)。

  3. 参数平滑过渡
    若需更平滑的切换,可对参数进行插值过渡(如线性渐变)。

  4. 参数校验
    可在 apply_params 中添加范围检查,防止非法值:

    if (params->Kp < 0 || params->Ki < 0 || params->Kd < 0) {
        bk_printf("[ERROR] Invalid PID parameters!\r\n");
        return;
    }
    

完整调用示例

// 手动触发参数切换测试
void test_switch_params(void) {
    if (current_state == PID_STATE_STEADY) {
        apply_params(&fast_params);
        current_state = PID_STATE_TRACKING;
    } else {
        apply_params(&slow_params);
        current_state = PID_STATE_STEADY;
    }
}

通过这种设计,PID 参数可以根据系统状态动态调整,在响应速度和稳定性之间取得平衡。

相关文章:

  • 评价区动态加载是怎么实现的?
  • 【AI学习】初步了解Gradio
  • Motionface MFvector照片一键转矢量工具使用教程
  • LeetCode算法题(Go语言实现)_34
  • 排序扩展-文件递归排序(外排序)
  • [ERROR] Some problems were encountered while processing the POMs
  • 鸿蒙开发_ARKTS快速入门_语法说明_组件声明_组件手册查看---纯血鸿蒙HarmonyOS5.0工作笔记010
  • 1631. 最小体力消耗路径
  • Quartz 数据持久化 接入MySQL数据库 数据不丢失 数据入库
  • 人工智能通识速览(Part4. 评估指标)
  • Android WiFi协议之P2P介绍与实践
  • git功能点管理
  • Redis 与 MongoDB 对比分析
  • Stable Diffusion XL、SD3 与 Flux 模型常用优化器总结
  • 【群晖】挂载小雅alist到AList网盘中
  • Android Automotive车载系统面试题及参考答案
  • Swift语言的云存储
  • 11231231
  • 轨检探伤专用一体机平板电脑:为铁路安全保驾护航
  • docker的几种网络模式
  • 中青报聚焦上海社区心理服务:社工介入让居民“心畅”
  • 男子服用头孢后饮酒应酬致昏迷在家,救援人员破门施救后脱险
  • 海南省检察院专委李思阳被带走,去年曾遭人举报违规插手案件
  • 脱欧后首次英欧峰会召开前夕,双方却因渔业和青年流动议题僵住了
  • 外交部:将持续便利中外人员往来,让“中国游”金字招牌更加闪耀
  • 左手免费午餐右手花开岭,邓飞14年公益之路的中国贡献