def pid(kp=<NUM_LIT:0.>, ki=<NUM_LIT:0.>, kd=<NUM_LIT:0.>, smooth=<NUM_LIT:0.1>):
state = dict(p=<NUM_LIT:0>, i=<NUM_LIT:0>, d=<NUM_LIT:0>)<EOL>def control(error, dt=<NUM_LIT:1>):<EOL><INDENT>state['<STR_LIT:d>'] = smooth * state['<STR_LIT:d>'] + (<NUM_LIT:1> - smooth) * (error - state['<STR_LIT:p>']) / dt<EOL>state['<STR_LIT:i>'] += error * dt<EOL>state['<STR_LIT:p>'] = error<EOL>return kp * state['<STR_LIT:p>'] + ki * state['<STR_LIT:i>'] + kd * state['<STR_LIT:d>']<EOL><DEDENT>return control<EOL>
r'''Create a callable that implements a PID controller.

    A PID controller returns a control signal :math:`u(t)` given a history of
    error measurements :math:`e(0) \dots e(t)`, using proportional (P), integral
    (I), and derivative (D) terms, according to:

    .. math::

       u(t) = kp * e(t) + ki * \int_{s=0}^t e(s) ds + kd * \frac{de(s)}{ds}(t)

    The proportional term is just the current error, the integral term is the
    sum of all error measurements, and the derivative term is the instantaneous
    derivative of the error measurement.

    Parameters
    ----------
    kp : float
        The weight associated with the proportional term of the PID controller.
    ki : float
        The weight associated with the integral term of the PID controller.
    kd : float
        The weight associated with the derivative term of the PID controller.
    smooth : float in [0, 1]
        Derivative values will be smoothed with this exponential average. A
        value of 1 never incorporates new derivative information, a value of 0.5
        uses the mean of the historic and new information, and a value of 0
        discards historic information (i.e., the derivative in this case will be
        unsmoothed). The default is 0.1.

    Returns
    -------
    controller : callable (float, float) -> float
        Returns a function that accepts an error measurement and a delta-time
        value since the previous measurement, and returns a control signal.