Control Feedforward en WPILib

Hasta ahora, hemos utilizado el control de retroalimentación para el seguimiento de referencias (hacer que la salida de un sistema siga una señal de referencia deseada). Si bien esto es efectivo, es una medida reaccionaria; el sistema no comenzará a aplicar esfuerzo de control hasta que el sistema ya esté retrasado. Si pudiéramos decirle al controlador sobre el movimiento deseado y la entrada requerida de antemano, el sistema podría reaccionar más rápido y el controlador de retroalimentación podría hacer menos trabajo. Un controlador que envía información a la planta de esta manera se denomina controlador de avance.

Un controlador de retroalimentación inyecta información sobre la dinámica del sistema (como lo hace un modelo matemático) o el movimiento previsto. Feedforward maneja partes de las acciones de control que ya sabemos que deben aplicarse para hacer que un seguimiento del sistema sea una referencia, luego la retroalimentación compensa lo que no sabemos o no podemos saber sobre el comportamiento del sistema en tiempo de ejecución.

Hay dos tipos de feedforwards: feedforward basado en modelos y feedforward para dinámicas no modeladas. El primero resuelve un modelo matemático del sistema para las entradas requeridas para alcanzar las velocidades y aceleraciones deseadas. El segundo compensa directamente las fuerzas o los comportamientos no modelados para que el controlador de retroalimentación no tenga que hacerlo. Ambos tipos pueden facilitar controladores de retroalimentación más simples. Cubriremos varios ejemplos a continuación.

Nota

Las clases de feedforward de WPILib coinciden estrechamente con las herramientas de caracterización de mecanismos disponibles en conjunto de herramientas de frc-characterization - el conjunto de herramientas de caracterización se puede utilizar para determinar rápida y efectivamente las ganancias correctas para cada tipo de feedforward. El conjunto de herramientas indicará las unidades apropiadas para cada una de las ganancias.

WPILib proporciona una serie de clases para ayudar a los usuarios a implementar un control de retroalimentación preciso para sus mecanismos. En muchos sentidos, una retroalimentación precisa es más importante que la retroalimentación para el control efectivo de un mecanismo. Dado que la mayoría de los mecanismos de FRC® obedecen de cerca a las ecuaciones del sistema bien entendidas, comenzar con un feedforward preciso es fácil y enormemente beneficioso para un control de mecanismo preciso y robusto.

WPILib actualmente proporciona las siguientes tres clases auxiliares para el control anticipado:

SimpleMotorFeedforward

Nota

En C ++, la clase SimpleMotorFeedforward se basa en el tipo de unidad utilizada para las mediciones de distancia, que puede ser angular o lineal. Las ganancias pasadas deben tener unidades consistentes con las unidades de distancia, o se arrojará un error de tiempo de compilación. kS debe tener unidades de voltios , kV debe tener unidades de voltios*segundos / distancia y kA debe tener unidades de ``voltios*segundos^2 / distancia ``. Para obtener más información sobre las unidades C++, consulte docs/software/basic-planning/cpp-units:The C ++ Units Library.

Nota

Los componentes de feedforward de Java calcularán los resultados en unidades determinadas por las unidades de las ganancias de feedforward proporcionadas por el usuario. Los usuarios deben tener cuidado de mantener las unidades consistentes, ya que WPILibJ no tiene un sistema de unidad de tipo seguro.

La clase SimpleMotorFeedforward calcula el feedforward para mecanismos que constan de motores DC de imanes permanentes sin carga externa más que fricción e inercia, como volantes y accionamientos de robots.

Para crear un SimpleMotorFeedforward, simplemente constrúyalo con las ganancias requeridas:

Nota

La ganancia de kA se puede omitir y, si es así, tendrá un valor predeterminado de cero. Para muchos mecanismos, especialmente aquellos con poca inercia, no es necesario.

// Create a new SimpleMotorFeedforward with gains kS, kV, and kA
SimpleMotorFeedforward feedforward = new SimpleMotorFeedforward(kS, kV, kA);

Para calcular el feedforward, simplemente llame al método calculate() con la velocidad y aceleración deseadas del motor:

Nota

El argumento de aceleración se puede omitir de la llamada calculate() y, si es así, se tomará por defecto un valor de cero. Esto debe hacerse siempre que no haya un punto de ajuste de aceleración claramente definido.

// Calculates the feedforward for a velocity of 10 units/second and an acceleration of 20 units/second^2
// Units are determined by the units of the gains passed in at construction.
feedforward.calculate(10, 20);

ArmFeedforward

Nota

En C++, la clase ArmFeedforward asume que las distancias son angulares, no lineales. Las ganancias pasadas * deben * tener unidades consistentes con la unidad angular, o se producirá un error en tiempo de compilación. kS y kCos deben tener unidades de voltios, kV debe tener unidades de voltios * segundos / radianes y kA debe tener unidades de voltios * segundos ^ 2 / radianes. Para obtener más información sobre las unidades C++, consulte docs/software/basic-planning/cpp-units:The C++ Units Library.

Nota

Los componentes de feedforward de Java calcularán los resultados en unidades determinadas por las unidades de las ganancias de feedforward proporcionadas por el usuario. Los usuarios deben tener cuidado de mantener las unidades consistentes, ya que WPILibJ no tiene un sistema de unidad de tipo seguro.

La clase ArmFeedforward calcula el feedforwards para brazos que están controlados directamente por un motor DC de imán permanente, con carga externa de fricción, inercia y masa del brazo. Este es un modelo preciso de la mayoría de los brazos en FRC.

Para crear un ArmFeedforward, simplemente constrúyalo con las ganancias requeridas:

Nota

La ganancia de kA se puede omitir y, si es así, tendrá un valor predeterminado de cero. Para muchos mecanismos, especialmente aquellos con poca inercia, no es necesario.

// Create a new ArmFeedforward with gains kS, kCos, kV, and kA
ArmFeedforward feedforward = new ArmFeedforward(kS, kCos, kV, kA);

Para calcular el feedforward, simplemente llame al método `` calculate () `` con la posición, velocidad y aceleración deseadas del brazo:

Nota

El argumento de aceleración se puede omitir de la llamada calculate() y, si es así, se tomará por defecto un valor de cero. Esto debe hacerse siempre que no haya un punto de ajuste de aceleración claramente definido.

// Calculates the feedforward for a position of 1 units, a velocity of 2 units/second, and
// an acceleration of 3 units/second^2
// Units are determined by the units of the gains passed in at construction.
feedforward.calculate(1, 2, 3);

ElevatorFeedforward

Nota

En C++, la clase``ElevatorFeedforward`` se basa en el tipo de unidad utilizado para las mediciones de distancia, que puede ser angular o lineal. Las ganancias pasadas deben tener unidades consistentes con las unidades de distancia, o se arrojará un error de tiempo de compilación. kS y kG deben tener unidades de voltios, kV debe tener unidades de voltios * segundos / distancia y kA debe tener unidades de voltios * segundos^2 / distancia. Para obtener más información sobre las unidades C++, consulte docs/software/basic-planning/cpp-units:The C ++ Units Library.

Nota

Los componentes de feedforward de Java calcularán los resultados en unidades determinadas por las unidades de las ganancias de feedforward proporcionadas por el usuario. Los usuarios deben tener cuidado de mantener las unidades consistentes, ya que WPILibJ no tiene un sistema de unidad de tipo seguro.

La clase ElevatorFeedforward calcula el feedforwards para ascensores que consisten en motores DC de imán permanente cargados por fricción, inercia y la masa del ascensor. Este es un modelo preciso de la mayoría de los ascensores en FRC.

Para crear un ElevatorFeedforward, simplemente constrúyalo con las ganancias requeridas:

Nota

La ganancia de kA se puede omitir y, si es así, tendrá un valor predeterminado de cero. Para muchos mecanismos, especialmente aquellos con poca inercia, no es necesario.

// Create a new ElevatorFeedforward with gains kS, kG, kV, and kA
ElevatorFeedforward feedforward = new ElevatorFeedforward(kS, kG, kV, kA);

Para calcular el feedforward, simplemente llame al método calculate() con la velocidad y aceleración deseadas del motor:

Nota

El argumento de aceleración se puede omitir de la llamada calculate() y, si es así, se tomará por defecto un valor de cero. Esto debe hacerse siempre que no haya un punto de ajuste de aceleración claramente definido.

// Calculates the feedforward for a position of 10 units, velocity of 20 units/second,
// and an acceleration of 30 units/second^2
// Units are determined by the units of the gains passed in at construction.
feedforward.calculate(10, 20, 30);

Uso de Feedforward para controlar los mecanismos

Nota

Dado que los voltajes de alimentación directa son físicamente significativos, es mejor usar el método setVoltage() (Java, C++) al aplicarlos a los motores para compensar la «caída de voltaje» de la batería.

El control Feedforward se puede utilizar completamente por sí solo, sin un controlador de retroalimentación. Esto se conoce como control de «bucle abierto» y para muchos mecanismos (especialmente los accionamientos de robots) puede resultar perfectamente satisfactorio. Se puede emplear un SimpleMotorFeedforward para controlar el accionamiento de un robot de la siguiente manera:

public void tankDriveWithFeedforward(double leftVelocity, double rightVelocity) {
  leftMotor.setVoltage(feedforward.calculate(leftVelocity));
  rightMotor.setVoltage(feedForward.calculate(rightVelocity));
}