Combinando prealimentación y Control PID

Nota

Este artículo cubre la implementación en código del control PID / prealimentación combinado con las clases de biblioteca proporcionadas por WPILib. Próximamente se publicará documentación que describe los conceptos involucrados con más detalle.

Los controladores de realimentación y retroalimentación se pueden usar de forma aislada, pero son más efectivos cuando se combinan. Afortunadamente, combinar estos dos métodos de control es extremadamente sencillo - uno simplemente suma sus resultados.

Usando prealimentación con un PIDController

Los usuarios familiarizados con la antigua clase PIDController pueden notar la falta de cualquier ganancia de retroalimentación en el nuevo controlador. Como se espera que los usuarios utilicen la salida del controlador ellos mismos, ya no es necesario que el PIDController implemente el feedforward - los usuarios pueden simplemente agregar cualquier feedforward que deseen a la salida del controlador antes de enviarlo a sus motores:

// Adds a feedforward to the loop output before sending it to the motor
motor.setVoltage(pid.calculate(encoder.getDistance(), setpoint) + feedforward);

Además, feedforward es una característica completamente separada de la retroalimentación y, por lo tanto, no tiene ninguna razón para manejarse en el mismo objeto de controlador, ya que esto viola la separación de preocupaciones. WPILib viene con varias clases auxiliares para calcular voltajes de retroalimentación precisos para mecanismos FRC|reg| - para obtener más información, consulte Control Feedforward en WPILib.

Uso de componentes Feedforward con PID

Nota

Since feedforward voltages are physically meaningful, it is best to use the setVoltage() (Java, C++) method when applying them to motors to compensate for «voltage sag» from the battery.

¿Cómo sería un ejemplo más completo de control PID / prealimentación combinado? Considera el drive example de la página de prealimentación. Podemos modificar esto fácilmente para incluir control de retroalimentación (con un componente SimpleMotorFeedforward):

public void tankDriveWithFeedforwardPID(double leftVelocitySetpoint, double rightVelocitySetpoint) {
  leftMotor.setVoltage(feedforward.calculate(leftVelocitySetpoint)
      + leftPID.calculate(leftEncoder.getRate(), leftVelocitySetpoint));
  rightMotor.setVoltage(feedForward.calculate(rightVelocitySetpoint)
      + rightPID.calculate(rightEncoder.getRate(), rightVelocitySetpoint));
}

Otros tipos de mecanismos se pueden manejar de manera similar.