class PID:
    """Afgeleide op meting; integrale toestand heeft eenheid watt."""
    def __init__(self, kp, ki, kd, maximum, begin=0, tau_d=60, tau_aw=600):
        if not all(finite(x) for x in (kp, ki, kd, maximum, begin, tau_d, tau_aw)):
            raise ValueError("niet-eindige PID-instelling")
        if min(kp, ki, kd) < 0 or min(maximum, tau_d, tau_aw) <= 0:
            raise ValueError("ongeldige PID-instelling")
        self.kp, self.ki, self.kd = kp, ki, kd
        self.maximum, self.I = maximum, begin
        self.tau_d, self.tau_aw = tau_d, tau_aw
        self.vorig, self.d = None, 0.0

    def vraag(self, setpoint, y, dt):
        if not all(finite(a) for a in (setpoint, y, dt)) or dt <= 0:
            raise ValueError("ongeldige PID-invoer")
        afgeleid = 0 if self.vorig is None else (y-self.vorig)/dt
        a = math.exp(-dt/self.tau_d)
        self.d = a*self.d+(1-a)*afgeleid
        self.vorig = y
        self.e = setpoint-y
        self.onbegrensd = self.kp*self.e+self.I-self.kd*self.d
        return min(self.maximum, max(0.0, self.onbegrensd))

    def terug(self, werkelijk, dt, aw=True):
        correctie = (werkelijk-self.onbegrensd)/self.tau_aw if aw else 0
        self.I += dt*(self.ki*self.e+correctie)
