WPILib’de Feedforward Kontrolü

Not

This article focuses on in-code implementation of feedforward control in WPILib. For a conceptual explanation of the feedforward equations used by WPILib, see Introduction to DC Motor Feedforward

You may have used feedback control (such as PID) for reference tracking (making a system’s output follow a desired reference signal). While this is effective, it’s a reactionary measure; the system won’t start applying control effort until the system is already behind. If we could tell the controller about the desired movement and required input beforehand, the system could react quicker and the feedback controller could do less work. A controller that feeds information forward into the plant like this is called a feedforward controller.

A feedforward controller injects information about the system’s dynamics (like a mathematical model does) or the intended movement. Feedforward handles parts of the control actions we already know must be applied to make a system track a reference, then feedback compensates for what we do not or cannot know about the system’s behavior at runtime.

The WPILib Feedforward Classes

WPILib, kullanıcıların mekanizmaları için doğru ileri besleme kontrolü uygulamalarına yardımcı olmak için bir dizi sınıf sağlar. Birçok yönden, doğru bir ileri besleme, bir mekanizmanın etkili kontrolü için geri bildirimden daha önemlidir. Çoğu FRC ® mekanizmalar, iyi anlaşılmış sistem denklemlerine yakından uyar, doğru bir ileri beslemeyle başlamak, doğru ve sağlam mekanizma kontrolü için hem kolay hem de büyük ölçüde faydalıdır.

The WPILib feedforward classes closely match the available mechanism characterization tools available in the SysId toolsuite. The system identification toolsuite can be used to quickly and effectively determine the correct gains for each type of feedforward. If you are unable to empirically characterize your mechanism (due to space and/or time constraints), reasonable estimates of kG, kV, and kA can be obtained by fairly simple computation, and are also available from ReCalc. kS is nearly impossible to model, and must be measured empirically.

WPILib şu anda feedforward denetimi için aşağıdaki üç yardımcı sınıfı sağlar:

SimpleMotorFeedforward

Not

C ++ ‘da, SimpleMotorFeedforward sınıfı, açısal veya doğrusal olabilen mesafe ölçümleri için kullanılan birim türüne göre şablonlanır. Kabul edilen kazançlar, mesafe birimleriyle tutarlı birimlere sahip olmalıdır, yoksa bir derleme zamanı hatası alınır. kS birimleri volt, kV birimleri volt * saniye / mesafe ve kA'' birimleri ``volt * saniye^2 / mesafe olmalıdır. C ++ birimleri hakkında daha fazla bilgi için bkz C ++ Ünite Kitaplığı.

Not

Java feedforward bileşenleri, çıktıları, kullanıcı tarafından sağlanan feedforward kazançlarının birimleri cinsinden hesaplar. WPILibJ’in güvenli-tip bir unit sistemi olmadığı için kullanıcılar unitleri tutarlı tutmaya özen göstermelidir.

Not

The API documentation for Python feedforward components indicate which unit is being used as wpimath.units.NAME. Users must take care to use correct units, as Python does not have a type-safe unit system.

SimpleMotorFeedforward sınıfı, dönen tekerlekler ve robot sürücüler gibi sürtünme ve atalet dışında hiçbir harici yüke sahip olmayan sabit mıknatıslı DC motorlardan oluşan mekanizmalar için ileri beslemeyi hesaplar.

Bir SimpleMotorFeedforward oluşturmak için, basitçe gerekli kazançları kullanın:

Not

kA kazancı ihmal edilebilir ve eğer öyleyse, varsayılan olarak sıfır değerine ayarlanır. Bu pek çok mekanizma için, özellikle az eylemsizliği olanlar için gerekli değildir.

// Create a new SimpleMotorFeedforward with gains kS, kV, and kA
SimpleMotorFeedforward feedforward = new SimpleMotorFeedforward(kS, kV, kA);
// Create a new SimpleMotorFeedforward with gains kS, kV, and kA
// Distance is measured in meters
frc::SimpleMotorFeedforward<units::meters> feedforward(kS, kV, kA);
from wpimath.controller import SimpleMotorFeedforwardMeters

# Create a new SimpleMotorFeedforward with gains kS, kV, and kA
# Distance is measured in meters
feedforward = SimpleMotorFeedforwardMeters(kS, kV, kA)

Feedforward hesaplamak için, istenen motor hızı ve ivmesiyle calculate() yöntemini çağırmanız yeterlidir:

Not

İvme argümanı calculate() çağrısından çıkarılabilir ve eğer öyleyse, varsayılan olarak sıfır değerine ayarlanır. Bu, açıkça tanımlanmış bir ivmelenme ayar noktası olmadığında yapılmalıdır.

// 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);
// Calculates the feedforward for a velocity of 10 meters/second and an acceleration of 20 meters/second^2
// Output is in volts
feedforward.Calculate(10_mps, 20_mps_sq);
# Calculates the feedforward for a velocity of 10 meters/second and an acceleration of 20 meters/second^2
# Output is in volts
feedforward.calculate(10, 20)

ArmFeedforward

Not

In C++, the ArmFeedforward class assumes distances are angular, not linear. The passed-in gains must have units consistent with the angular unit, or a compile-time error will be thrown. kS and kG should have units of volts, kV should have units of volts * seconds / radians, and kA should have units of volts * seconds^2 / radians. For more information on C++ units, see C ++ Ünite Kitaplığı.

Not

Java feedforward bileşenleri, çıktıları, kullanıcı tarafından sağlanan feedforward kazançlarının birimleri cinsinden hesaplar. WPILibJ’in güvenli-tip bir unit sistemi olmadığı için kullanıcılar unitleri tutarlı tutmaya özen göstermelidir.

Not

The API documentation for Python feedforward components indicate which unit is being used as wpimath.units.NAME. Users must take care to use correct units, as Python does not have a type-safe unit system.

ArmFeedforward sınıfı, doğrudan kalıcı mıknatıslı bir DC motor tarafından kontrol edilen kollar için sürtünme, atalet ve kol kütlesinin harici yüklemesi ile ileri beslemeyi hesaplar. Bu, FRC’deki çoğu kol için doğru bir modelidir.

Bir ArmFeedforward oluşturmak için, onu gerekli kazançlarla ayarlamanız yeterlidir:

Not

kA kazancı ihmal edilebilir ve eğer öyleyse, varsayılan olarak sıfır değerine ayarlanır. Bu pek çok mekanizma için, özellikle az eylemsizliği olanlar için gerekli değildir.

// Create a new ArmFeedforward with gains kS, kG, kV, and kA
ArmFeedforward feedforward = new ArmFeedforward(kS, kG, kV, kA);
// Create a new ArmFeedforward with gains kS, kG, kV, and kA
frc::ArmFeedforward feedforward(kS, kG, kV, kA);
from wpimath.controller import ArmFeedforward

# Create a new ArmFeedforward with gains kS, kG, kV, and kA
feedforward = ArmFeedforward(kS, kG, kV, kA)

Feedforward hesaplamak için, istenen kol konumu, hızı ve ivmeyle calculate() yöntemini çağırmanız yeterlidir:

Not

İvme argümanı calculate() çağrısından çıkarılabilir ve eğer öyleyse, varsayılan olarak sıfır değerine ayarlanır. Bu, açıkça tanımlanmış bir ivmelenme ayar noktası olmadığında yapılmalıdır.

// 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);
// Calculates the feedforward for a position of 1 radians, a velocity of 2 radians/second, and
// an acceleration of 3 radians/second^2
// Output is in volts
feedforward.Calculate(1_rad, 2_rad_per_s, 3_rad/(1_s * 1_s));
# Calculates the feedforward for a position of 1 radians, a velocity of 2 radians/second, and
# an acceleration of 3 radians/second^2
# Output is in volts
feedforward.calculate(1, 2, 3)

ElevatorFeedforward

Not

In C++, the passed-in gains must have units consistent with the distance units, or a compile-time error will be thrown. kS and kG should have units of volts, kV should have units of volts * seconds / distance, and kA should have units of volts * seconds^2 / distance. For more information on C++ units, see C ++ Ünite Kitaplığı.

Not

Java feedforward bileşenleri, çıktıları, kullanıcı tarafından sağlanan feedforward kazançlarının birimleri cinsinden hesaplar. WPILibJ’in güvenli-tip bir unit sistemi olmadığı için kullanıcılar unitleri tutarlı tutmaya özen göstermelidir.

Not

The API documentation for Python feedforward components indicate which unit is being used as wpimath.units.NAME. Users must take care to use correct units, as Python does not have a type-safe unit system.

ElevatorFeedforward sınıfı, sürtünme, atalet ve asansör kütlesi ile yüklenen sabit mıknatıslı DC motorlardan oluşan asansörler için feedforward hesaplar. Bu, FRC’deki çoğu asansörün uygun bir modelidir.

ElevatorFeedforward oluşturmak için, onu gerekli kazançlarla yapılandırmanız yeterlidir:

Not

kA kazancı ihmal edilebilir ve eğer öyleyse, varsayılan olarak sıfır değerine ayarlanır. Bu pek çok mekanizma için, özellikle az eylemsizliği olanlar için gerekli değildir.

// Create a new ElevatorFeedforward with gains kS, kG, kV, and kA
ElevatorFeedforward feedforward = new ElevatorFeedforward(kS, kG, kV, kA);
// Create a new ElevatorFeedforward with gains kS, kV, and kA
// Distance is measured in meters
frc::ElevatorFeedforward feedforward(kS, kG, kV, kA);
from wpimath.controller import ElevatorFeedforward

# Create a new ElevatorFeedforward with gains kS, kV, and kA
# Distance is measured in meters
feedforward = ElevatorFeedforward(kS, kG, kV, kA)

Feedforward hesaplamak için, istenen motor hızı ve ivmesiyle calculate() yöntemini çağırmanız yeterlidir:

Not

İvme argümanı calculate() çağrısından çıkarılabilir ve eğer öyleyse, varsayılan olarak sıfır değerine ayarlanır. Bu, açıkça tanımlanmış bir ivmelenme ayar noktası olmadığında yapılmalıdır.

// Calculates the feedforward for a 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(20, 30);
// Calculates the feedforward for a velocity of 20 meters/second
// and an acceleration of 30 meters/second^2
// Output is in volts
feedforward.Calculate(20_mps, 30_mps_sq);
# Calculates the feedforward for a velocity of 20 meters/second
# and an acceleration of 30 meters/second^2
# Output is in volts
feedforward.calculate(20, 30)

Kontrol Mekanizmaları için Feedforward 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 kontrolü, bir geri bildirim denetleyicisi olmadan tamamen kendi başına kullanılabilir. Bu, “açık döngü” kontrolü olarak bilinir ve birçok mekanizma için (özellikle robot sürücüler) mükemmel şekilde tatmin edici olabilir. Bir robot sürücüsünü aşağıdaki şekilde kontrol etmek için bir SimpleMotorFeedforward kullanılabilir:

public void tankDriveWithFeedforward(double leftVelocity, double rightVelocity) {
  leftMotor.setVoltage(feedforward.calculate(leftVelocity));
  rightMotor.setVoltage(feedForward.calculate(rightVelocity));
}
void TankDriveWithFeedforward(units::meters_per_second_t leftVelocity,
                              units::meters_per_second_t rightVelocity) {
  leftMotor.SetVoltage(feedforward.Calculate(leftVelocity));
  rightMotor.SetVoltage(feedforward.Calculate(rightVelocity));
}
def tankDriveWithFeedforward(self, leftVelocity: float, rightVelocity: float):
    self.leftMotor.setVoltage(feedForward.calculate(leftVelocity))
    self.rightMotor.setVoltage(feedForward.calculate(rightVelocity))