腾讯pid调速问题

// 此模板仅供参考,如果不适用可以修改

问题描述

闭源代码传入pstTarTemp结构体

其中cSetPWM 取自pstTarTemp的ucSetPWM,temp_pwm_duty为计算出的增量PID值,打印代码如下

if (access("/data/MIXDebug", 0) == 0) {

    printf(" Calculated Increased PID= %d;", temp_pwm_duty);

    printf(" Last calculate PID value = %d;", cSetPWM);



    gint32 output_pwm_duty = cSetPWM + temp_pwm_duty;

    printf(" calculate PID value = %d;", output_pwm_duty);

    printf("   Kp\[%.2f\] Ki\[%.2f\] Kd\[%.2f\];", temp_kp, temp_ki, temp_kd);

    printf("   Error0\[%d\] Error1\[%d\] Error2\[%d\];", error_value, sensor_table->Error_history\[1\], sensor_table->Error_history\[2\]);

    printf("   Temp0\[%d\] Temp1\[%d\] Temp2\[%d\] Temp3\[%d\] Temp4\[%d\] SensorTempAverage\[%d\];",

        sensor_table->Temp\[0\], sensor_table->Temp\[1\], sensor_table->Temp\[2\], sensor_table->Temp\[3\], sensor_table->Temp\[4\], sensor_temp_average);

    printf("   Max_PWM_Up=%d Max_PWM_Down=%d;\\n", max_pwm_up, max_pwm_down);

}

日志显示如下,传入的cSetPWM应该为上次计算的PID值78,thermal_mgmt仓无报错

答案内容由AI生成,仅供参考:

:pushpin: 结论

当前PID调速系统的 cSetPWM 输入异常(应为78但取了128),并非计算错误,而是多路径调速融合机制与状态维护脱节所致。建议重构调速架构,实现路径隔离 + 状态本地化 + 融合前合并,以保证PID控制的连续性和准确性。

点击此处查看详细分析解答

腾讯PID调速问题分析

根据提供的日志信息和代码逻辑,系统存在PID控制输出不一致的问题。具体表现为:当前次计算出的PID输出值应为上次的最终输出值,但实际传入的 cSetPWM 值与预期不符(本应为78,实际为128),导致控制链断裂,影响调速稳定性。


:magnifying_glass_tilted_left: 问题描述

在PID调速控制流程中,使用增量式PID算法进行风扇转速调控。核心计算逻辑如下:

gint32 output_pwm_duty = cSetPWM + temp_pwm_duty;

其中:

  • cSetPWM:来自上一次PID计算的结果(即上次的 output_pwm_duty)。
  • temp_pwm_duty:本次的增量输出(由P、I、D项计算得出)。
  • 最终 output_pwm_duty 作为本次PWM占空比设定值下发给风扇控制器。

日志关键信息

Temperature= 90; Target Temperature= 90;
Calculated Increased PID = 27;
Last calculate PID value = 51;
calculate PID value = 78;
...
Last calculate PID value = 128;  // ❌ 应该是78,却变成了128

从日志序列看:

  1. 初始阶段,上一次输出值为78。
  2. 下一轮循环中,期望 cSetPWM = 78
  3. 实际传入值为128,表明:
    • 上一次的结果未被正确保存或传递;
    • 或者中间有其他控制逻辑强制修改了 cSetPWM
    • 存在并发、异步覆盖或状态不同步的风险。

:puzzle_piece: 问题定位分析(基于知识库与上下文)

尽管当前环境为“腾讯”背景,但结合 thermal_mgmtCoolingRequirementPID Control Algorithm 等通用机制,可推断其底层架构类似:

实体/对象 角色
PID控制算法 负责根据器件温度与目标温度的偏差调节风扇PWM
CoolingRequirement 定义每个设备的调速需求,包括目标温度 TargetTemperatureCelsius 和当前温度 T
thermal_mgmt 模块 主控服务,协调PID参数、目标值、实际反馈之间的关系
fan_obj_manager::set_fan_hardware_pwm 底层接口,用于将最终PWM写入硬件
可能原因分析:
  1. 状态未持久化或被重置

    • cSetPWM 可能未在控制器中长期保存,而是从外部重新加载,导致丢失最新值。
    • 若系统检测到某种异常(如传感器漂移、模式切换),可能重设初始值为默认值128。
  2. 多路调速策略竞争(目标调速 vs 环温调速)
    根据知识库中的日志字段:

    DevID:0x101, T:52, TarT:48, TarPWM:135, EnvTNum:1, EnvPWM:89, PIDPWM:135
    
    • TarPWM:目标调速计算出的PWM;
    • EnvPWM:环境温控调速计算出的PWM;
    • PIDPWM:最终选择的最大值

    :warning: 说明:系统采用“最大值选择”策略,即多条调速路径并行运行,最终PWM取最大值。

    推论

    • 在日志中 cSetPWM=128 可能源于“环温调速”或其他异常调速路径输出;
    • 而目标调速前一轮输出为78,但被系统整体调度器替换为128;
    • 下一次调用时传入的是全局最大值,而非本路径的历史值 → 导致非连续控制
  3. 状态不同步或数据竞争(并发问题)

    • PID计算分布在不同线程或异步任务中;
    • 共享变量 cSetPWM 未加锁保护,造成写入冲突;
    • 日志显示多条相同温度下重复计算,表明周期性执行中存在不一致。
  4. 自定义控制逻辑干预(如快升慢降策略)
    根据 CSR 配置项 PIDControlMode(值为1-4)支持不同响应模式:

    • 快升快降
    • 慢升快降

    若启用“快升”策略,在温差大时可能直接跳变到高PWM(如128),但未通知上层维持此为“上一次输出”,造成断层。


:white_check_mark: 根本原因总结

:light_bulb: 根本原因:PID控制上下文中 cSetPWM 的上下文保持不一致,很可能是由于多源调速策略融合后覆盖了原路径的反馈值,导致增量PID无法连续积分。

  • 系统并非单一PID回路,而是多个调速源(目标调速、环温调速、异常调速、SmartCooling 模式)并行计算;
  • 最终取 max(PWM1, PWM2, ...) 作为 output_pwm_duty
  • 但在下一轮PID计算时,若仍用此最大值作为 cSetPWM,而该值来源于另一条调速路径,则破坏了原有回路的连续性;
  • 导致 积分项失灵、控制震荡、响应迟滞

这正是日志中出现“上次值应为78,却变成128”的根本原因。


:hammer_and_wrench: 解决建议

建议 说明
1. 按调速路径独立维护状态 对每条调速路径(如目标调速)单独保存其上一次的输出值 last_pwm,而不是共用一个全局的 cSetPWM
2. 区分“最终输出”与“路径中间结果” 最终下发PWM走最大值选择逻辑;但各子路径内部PID仍应基于自身历史值计算
3. 引入调试标识字段 在日志中增加调速源标识(如 Source=TargetPID or Source=EnvTemp),便于追踪来源
4. 校验 cSetPWM 来源一致性 添加断言或日志:若前一轮输出为78,本轮输入非78时打印警告
5. 使用增量PID标准形式 推荐采用标准增量式PID公式,避免依赖外部状态维护:
Δu(k) = Kp[e(k)−e(k−1)] + Ki·T·e(k) + Kd/T[e(k)−2e(k−1)+e(k−2)]
u(k) = u(k−1) + Δu(k)

并确保 u(k−1) 来自本路径保存的状态。


:pushpin: 结论

当前PID调速系统的 cSetPWM 输入异常(应为78但取了128),并非计算错误,而是多路径调速融合机制与状态维护脱节所致。建议重构调速架构,实现路径隔离 + 状态本地化 + 融合前合并,以保证PID控制的连续性和准确性。

当前PID计算采用的是PWM之前计算出的转速