y00051691
(kunlun_yajingtian)
1
// 此模板仅供参考,如果不适用可以修改
问题描述
闭源代码传入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生成,仅供参考:
结论
当前PID调速系统的 cSetPWM 输入异常(应为78但取了128),并非计算错误,而是多路径调速融合机制与状态维护脱节所致。建议重构调速架构,实现路径隔离 + 状态本地化 + 融合前合并,以保证PID控制的连续性和准确性。
点击此处查看详细分析解答
腾讯PID调速问题分析
根据提供的日志信息和代码逻辑,系统存在PID控制输出不一致的问题。具体表现为:当前次计算出的PID输出值应为上次的最终输出值,但实际传入的 cSetPWM 值与预期不符(本应为78,实际为128),导致控制链断裂,影响调速稳定性。
问题描述
在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
从日志序列看:
- 初始阶段,上一次输出值为78。
- 下一轮循环中,期望
cSetPWM = 78。
- 实际传入值为128,表明:
- 上一次的结果未被正确保存或传递;
- 或者中间有其他控制逻辑强制修改了
cSetPWM;
- 存在并发、异步覆盖或状态不同步的风险。
问题定位分析(基于知识库与上下文)
尽管当前环境为“腾讯”背景,但结合 thermal_mgmt、CoolingRequirement、PID Control Algorithm 等通用机制,可推断其底层架构类似:
| 实体/对象 |
角色 |
| PID控制算法 |
负责根据器件温度与目标温度的偏差调节风扇PWM |
| CoolingRequirement |
定义每个设备的调速需求,包括目标温度 TargetTemperatureCelsius 和当前温度 T |
| thermal_mgmt 模块 |
主控服务,协调PID参数、目标值、实际反馈之间的关系 |
| fan_obj_manager::set_fan_hardware_pwm |
底层接口,用于将最终PWM写入硬件 |
可能原因分析:
-
状态未持久化或被重置
cSetPWM 可能未在控制器中长期保存,而是从外部重新加载,导致丢失最新值。
- 若系统检测到某种异常(如传感器漂移、模式切换),可能重设初始值为默认值128。
-
多路调速策略竞争(目标调速 vs 环温调速)
根据知识库中的日志字段:
DevID:0x101, T:52, TarT:48, TarPWM:135, EnvTNum:1, EnvPWM:89, PIDPWM:135
TarPWM:目标调速计算出的PWM;
EnvPWM:环境温控调速计算出的PWM;
PIDPWM:最终选择的最大值;
说明:系统采用“最大值选择”策略,即多条调速路径并行运行,最终PWM取最大值。
推论:
- 在日志中
cSetPWM=128 可能源于“环温调速”或其他异常调速路径输出;
- 而目标调速前一轮输出为78,但被系统整体调度器替换为128;
- 下一次调用时传入的是全局最大值,而非本路径的历史值 → 导致非连续控制。
-
状态不同步或数据竞争(并发问题)
- PID计算分布在不同线程或异步任务中;
- 共享变量
cSetPWM 未加锁保护,造成写入冲突;
- 日志显示多条相同温度下重复计算,表明周期性执行中存在不一致。
-
自定义控制逻辑干预(如快升慢降策略)
根据 CSR 配置项 PIDControlMode(值为1-4)支持不同响应模式:
若启用“快升”策略,在温差大时可能直接跳变到高PWM(如128),但未通知上层维持此为“上一次输出”,造成断层。
根本原因总结
根本原因:PID控制上下文中 cSetPWM 的上下文保持不一致,很可能是由于多源调速策略融合后覆盖了原路径的反馈值,导致增量PID无法连续积分。
- 系统并非单一PID回路,而是多个调速源(目标调速、环温调速、异常调速、SmartCooling 模式)并行计算;
- 最终取
max(PWM1, PWM2, ...) 作为 output_pwm_duty;
- 但在下一轮PID计算时,若仍用此最大值作为
cSetPWM,而该值来源于另一条调速路径,则破坏了原有回路的连续性;
- 导致 积分项失灵、控制震荡、响应迟滞。
这正是日志中出现“上次值应为78,却变成128”的根本原因。
解决建议
| 建议 |
说明 |
| 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) 来自本路径保存的状态。
结论
当前PID调速系统的 cSetPWM 输入异常(应为78但取了128),并非计算错误,而是多路径调速融合机制与状态维护脱节所致。建议重构调速架构,实现路径隔离 + 状态本地化 + 融合前合并,以保证PID控制的连续性和准确性。