You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Python模块中PID控制器的初始化代码仅在首次调用时运行一次?

解决方案

现有实现的核心问题是每次调用函数都会重新实例化PID对象,丢失积分、微分历史状态,且重复执行不必要的初始化操作,按以下方式实现即可满足你的需求:

第一步:编写PID_module.py模块文件

from simple_pid import PID as SimplePID

# 以下为仅需执行一次的初始化逻辑,模块首次导入时自动运行
Kp = 80
Ki = 60
Kd = 0.01
pid = SimplePID(Kp, Ki, Kd)
pid.sample_time = 0.05
# 缓存变量,用于判断目标速度是否变更
_last_target_speed = None
_Kf = 0

def PID(rpm_array1, target_speed):
    global _last_target_speed, _Kf
    # 仅目标速度变化时更新设定值和前馈系数
    if target_speed != _last_target_speed:
        _last_target_speed = target_speed
        _Kf = 180 / target_speed
        pid.setpoint = target_speed
    
    # 每次调用都需要执行的实时运算逻辑
    avg_rpm_rear = (rpm_array1[2] + rpm_array1[3]) / 2
    speed = (avg_rpm_rear / 60) * 0.355

    x = pid(speed)
    pid_output = x + (target_speed * _Kf)
    
    throttle_target = pid_output + 1455 if pid_output > 0 else 1455
    # 油门输出限幅
    throttle_target = max(1455, min(throttle_target, 2500))
    return throttle_target

第二步:主代码调用

你无需修改原有期望的调用逻辑,直接按如下方式使用即可:

import PID_module

while True:
    # 传入实时采集的后轮转速数组和目标速度,直接得到目标油门值
    target_throttle = PID_module.PID(rpm_array1, target_speed)

实现说明

  • 模块顶层的初始化代码仅在第一次导入PID_module时执行一次,不会重复创建PID对象,可正确保留PID的积分、微分历史状态,保证控制效果
  • 修正了原始代码中PID类和自定义函数重名导致的命名冲突问题
  • 仅目标速度发生变化时才更新设定值和前馈系数,减少不必要的重复计算
  • 优化了油门限幅逻辑,代码更简洁易维护

内容的提问来源于stack exchange,提问作者SaguaroMaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:15:04