La acción derivativa de un PID es la parte del controlador que responde a la velocidad de cambio del error para amortiguar el movimiento del sistema.
En el artículo anterior vimos que la P empuja según el error actual y que la I acumula el error pasado. Nos falta la tercera pieza, la D, que mira la pendiente y dice: “ojo, que esto viene demasiado rápido”.
No corrige el presente ni el pasado. La derivada intenta oler el futuro. Dicho con menos poesía y más matemáticas: calcula si el error está creciendo o disminuyendo, y a qué velocidad.
La intuición de la D
Piensa en conducir un coche y parar en un semáforo. Si solo mirases la distancia al semáforo, frenarías cada vez más fuerte cuanto más cerca estés. Eso sería una acción proporcional.
Normalmente no conduces así (o eso espero). También miras la velocidad. Si vas rápido, empiezas a frenar antes. Si vas despacio, puedes apurar más.
La derivada hace algo parecido. Si el sistema se acerca muy rápido al objetivo, la D aplica una acción contraria para frenar antes de pasarse.
En sistemas de segundo orden, esto se interpreta como amortiguamiento artificial. Es como añadir un amortiguador por software.
La ecuación de la derivada
Matemáticamente, la acción derivativa se escribe así:
Kd es la ganancia derivativa. Cuanto mayor sea, más peso le damos a la velocidad de cambio del error.
En un microcontrolador, como no tenemos una derivada continua, usamos una diferencia finita:
Y en código:
float derivada = (error - error_anterior) / dt;
float D = Kd * derivada;
error_anterior = error;Conceptualmente es muy simple. Restamos el error actual menos el error anterior y dividimos entre el tiempo transcurrido. Eso nos da la pendiente.
Qué consigue la D
La acción derivativa suele reducir el overshoot y las oscilaciones. Es decir, ayuda a que el sistema llegue al objetivo sin pasarse tanto.
También puede mejorar el tiempo de asentamiento, porque amortigua los rebotes. Si la P hace que el sistema sea rápido pero nervioso, la D intenta ponerle un poco de cabeza.
Una D bien ajustada hace que el sistema parezca más «pesado» y controlado. Una D mal ajustada convierte el ruido del sensor en golpes de mando. Esto último pasa muchísimo.
El problema del ruido
La derivada tiene una debilidad importante: amplifica las señales rápidas.
Y el ruido de los sensores suele ser precisamente eso: pequeñas variaciones rápidas. Un ADC que baila un par de cuentas, un encoder con cuantización, un acelerómetro recogiendo vibraciones… todo eso puede parecer poca cosa en la señal original, pero al derivarlo se convierte en picos enormes.
Por eso en sistemas reales casi nunca se usa una derivada “pura”. Se suele filtrar la medida, filtrar la propia derivada, o aplicar la derivada sobre la variable medida en vez de sobre el error.
Derivada sobre la medida
Hay otro detalle práctico importante. Si calculamos la derivada del error, y de repente cambiamos el setpoint, el error pega un salto brusco. La derivada de ese salto es enorme, y el controlador genera un pico de salida que no corresponde a un movimiento real de la planta.
Eso se llama derivative kick.
Una solución habitual es calcular la derivada sobre la medida (PV) en lugar de sobre el error:
float derivada_medida = (medida - medida_anterior) / dt;
float D = -Kd * derivada_medida;El signo negativo aparece porque si la medida sube muy rápido hacia el objetivo, queremos frenar. Con esto evitamos que un cambio de referencia produzca un golpe derivativo artificial.
El PID completo
Uniendo las tres acciones, la forma clásica del PID continuo es:
Cada término mira una parte distinta de la historia:
- P: mira el error presente.
- I: acumula el error pasado.
- D: estima la tendencia futura.
Por eso el PID ha sobrevivido tantas décadas. No es porque sea perfecto, sino porque es simple, barato y sorprendentemente eficaz en una barbaridad de sistemas reales.
Implementación conceptual
Un PID básico en C++ quedaría así:
float Kp = 2.0;
float Ki = 0.5;
float Kd = 0.1;
float integral_acumulada = 0.0;
float error_anterior = 0.0;
float calcularPID(float setpoint, float medida, float dt) {
float error = setpoint - medida;
float P = Kp * error;
integral_acumulada += error * dt;
float I = Ki * integral_acumulada;
float derivada = (error - error_anterior) / dt;
float D = Kd * derivada;
error_anterior = error;
return P + I + D;
}Este código nos sirve para entender la estructura, pero todavía no es un PID listo para producción. Le faltan cosas importantes: límites de salida, anti-windup, filtrado de derivada y un tiempo de muestreo determinista.
No copies este PID básico tal cual en una máquina real sin añadir límites y protección contra saturación. Para aprender está bien. Para mover hardware con energía, se queda corto.
La derivada aporta amortiguamiento. Mira la velocidad con la que cambia el error y ayuda a frenar antes de pasarnos del objetivo.
Con P, I y D ya tenemos el controlador completo. La P nos da reacción, la I elimina el error permanente y la D suaviza los rebotes.