Feedforward - ileribesleme ve PID Kontrolünü Birleştirme

Not

Bu makale, WPILib’in sağladığı kütüphane sınıfları ile birlikte feedforward/PID kontrolünün kod içi uygulamasını kapsar. İlgili kavramları daha ayrıntılı olarak açıklayan belgeler yakında çıkacaktır.

Feedforward ve geri bildirim denetleyicilerinin her biri ayrı ayrı kullanılabilir, ancak birlikte kullanıldığında en etkilidir. Neyse ki, bu iki kontrol yöntemini birleştirmek son derece basittir - basitçe çıktılarını bir araya getirir.

Feedforward’ı bir PIDController ile kullanma

Users may add any feedforward they like to the output of the controller before sending it to their motors:

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

Dahası, ileri besleme, tamamen geri bildirimden ayrı bir özelliktir ve bu nedenle, endişelerin ayrılmasını ihlal ettiği için aynı denetleyici nesnesinde ele alınması için bir neden yoktur. WPILib, ortak FRC ® için doğru ileri besleme voltajlarını hesaplamak üzere birkaç yardımcı sınıfla birlikte gelir. mekanizmalar - daha fazla bilgi için bkz : ref: docs / software / advanced-controls / controller / feedforward: Feedforward Control in WPILib.

PID ile Feedforward Bileşenlerini Kullanma

Not

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

Feedforward / PID kontrolünün daha eksiksiz bir örneği neye benzeyebilir? Feedforward sayfasından sürüş örneği dikkate alınız. Geri bildirim kontrolünü dahil etmek için bunu kolayca değiştirebiliriz ( SimpleMotorFeedforward bileşeni ile)

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));
}
void TankDriveWithFeedforwardPID(units::meters_per_second_t leftVelocitySetpoint,
                                 units::meters_per_second_t rightVelocitySetpoint) {
  leftMotor.SetVoltage(feedforward.Calculate(leftVelocitySetpoint)
      + leftPID.Calculate(leftEncoder.getRate(), leftVelocitySetpoint.value()));
  rightMotor.SetVoltage(feedforward.Calculate(rightVelocitySetpoint)
      + rightPID.Calculate(rightEncoder.getRate(), rightVelocitySetpoint.value()));
}
def tank_drive_with_feedforward_PID(
    left_velocity_setpoint: float,
    right_velocity_setpoint: float,
) -> None:
    leftMotor.setVoltage(
        feedforward.calculate(left_velocity_setpoint)
        + leftPID.calculate(leftEncoder.getRate(), left_velocity_setpoint)
    )
    rightMotor.setVoltage(
        feedforward.calculate(right_velocity_setpoint)
        + rightPID.calculate(rightEncoder.getRate(), right_velocity_setpoint)
    )

Diğer mekanizma türleri de benzer şekilde ele alınabilir.