WPILib’de Trapezoid Hareket Profilleri

Not

Bu makale, trapezoidal hareket profillerinin kod içi üretimini kapsar. İlgili kavramları daha ayrıntılı olarak açıklayan belgeler yakında çıkacaktır.

Not

TrapezoidProfile sınıfının komut tabanlı framework çerçevesinde uygulanmasına ilişkin bir kılavuz için bkz TrapezProfileSubsystems ve TrapezoidProfileCommands ile Hareket Profilleme .

Not

Kendi başına kullanılan TrapezoidProfile sınıfı, özel bir kontrolörle (yerleşik PID işlevselliğine sahip “akıllı” bir motor kontrolörü gibi) oluşturulduğunda çok kullanışlıdır. Bir WPILib PIDController ile entegre etmek için, bakınız Motion Profiling ve PID Control’ü ProfiledPIDController ile Birleştirme.

İleri besleme ve geri bildirim kontrolü, belirli bir ayar noktasına ulaşmak için uygun yollar sunsa da, çoğu zaman mekanizmalarımız için ayar noktaları oluşturma sorunuyla karşı karşıyayız. Bir mekanizmaya derhal istenen duruma getirme komutu yaklaşımı işe yarayabilirken, çoğu zaman yetersizdir. Mekanizmalarımızın işlevini iyileştirmek için, mekanizmalara, mevcut durumu ile istenen hedef durumu arasında sorunsuz bir şekilde geçiş yapan bir dizi ayar noktasına komut vermek isteriz.

To help users do this, WPILib provides a TrapezoidProfile class (Java, C++).

Trapezoidal Profil Oluşturma

Not

C ++ ‘da, TrapezoidProfile ‘sınıfı, açısal veya doğrusal olabilen mesafe ölçümleri için kullanılan birim tipine göre şablonlanır. İletilen değerler zorunlu mesafe birimleriyle tutarlı birimlere sahip olmalıdır; aksi takdirde derleme zamanı hatası atılır. C ++ birimleri hakkında daha fazla bilgi için bkz . C ++ Ünite Kitaplığı.

Kısıtlamalar

Not

Çeşitli ileribesleme yardımcı sınıfları, bir mekanizmanın aynı anda elde edilebilen maksimum hızını ve ivmesini hesaplamak için yöntemler sağlar. Bunlar, TrapezoidProfile için uygun hareket kısıtlamalarını hesaplamak için çok yararlı olabilir.

In order to create a trapezoidal motion profile, we must first impose some constraints on the desired motion. Namely, we must specify a maximum velocity and acceleration that the mechanism will be expected to achieve during the motion. To do this, we create an instance of the TrapezoidProfile.Constraints class (Java, C++):

// Creates a new set of trapezoidal motion profile constraints
// Max velocity of 10 meters per second
// Max acceleration of 20 meters per second squared
new TrapezoidProfile.Constraints(10, 20);

Başlangıç ve Bitiş Durumları

Next, we must specify the desired starting and ending states for our mechanisms using the TrapezoidProfile.State class (Java, C++). Each state has a position and a velocity:

// Creates a new state with a position of 5 meters
// and a velocity of 0 meters per second
new TrapezoidProfile.State(5, 0);

Hepsini bir araya koymak

Not

C++ genellikle iç sınıfların türünü çıkarabilir ve bu nedenle basit bir başlatıcı listesi (sınıf adı olmadan) parametre olarak gönderilebilir. Tam sınıf adları, netlik açısından aşağıdaki örnekte verilmiştir.

Artık bir dizi kısıtlamayı ve istenen başlangıç / bitiş durumlarını nasıl oluşturacağımızı bildiğimize göre, hareket profilimizi oluşturmaya hazırız. TrapezoidProfile yapıcısı sırayla 3 parametre alır: kısıtlamalar-constraints, hedef durumu-goal state ve başlangıç durumu-initial state.

// Creates a new TrapezoidProfile
// Profile will have a max vel of 5 meters per second
// Profile will have a max acceleration of 10 meters per second squared
// Profile will end stationary at 5 meters
// Profile will start stationary at zero position
TrapezoidProfile profile = new TrapezoidProfile(new TrapezoidProfile.Constraints(5, 10),
                                                new TrapezoidProfile.State(5, 0),
                                                new TrapezoidProfile.State(0, 0));

Bir TrapezoidProfile Kullanmak

Profili Örnekleme

Bir TrapezoidProfile oluşturduktan sonra, onu kullanmak çok basittir: profil başladıktan sonra verilen zamanda profil durumunu elde etmek için calculate() yöntemini çağırın:

// Returns the motion profile state after 5 seconds of motion
profile.calculate(5);

Profil Durumunun Kullanılması

calculate yöntemi, bir TrapezoidProfile.State sınıfını döndürür (profili oluştururken başlangıç / bitiş durumlarını belirtmek için kullanılanla aynı). Bunu gerçek kontrol için kullanmak için, içerilen konum ve hız değerlerini dilediğiniz kontrolöre (örneğin, bir PIDController) aktarmanız yeterlidir:

var setpoint = profile.calculate(elapsedTime);
controller.calculate(encoder.getDistance(), setpoint.position);

Tam Kullanım Örneği

Not

In this example, the profile is re-computed every timestep. This is a somewhat different usage technique than is detailed above, but works according to the same principles - the profile is sampled at a time corresponding to the loop period to get the setpoint for the next loop iteration.

ElevatorTrapezoidProfile örnek projesinde TrapezoidProfile kullanımının daha eksiksiz bir örneği verilmiştir (Java <https://github.com/wpilibsuite/allwpilib/tree/main/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/elevatortrapezoidprofile> __, C ++ <https://github.com/wpilibsuite/allwpilib/tree/main/wpilibcExamples/src/main/cpp/examples/ElevatorTrapezoidProfile/cpp> __):

 5package edu.wpi.first.wpilibj.examples.elevatortrapezoidprofile;
 6
 7import edu.wpi.first.math.controller.SimpleMotorFeedforward;
 8import edu.wpi.first.math.trajectory.TrapezoidProfile;
 9import edu.wpi.first.wpilibj.Joystick;
10import edu.wpi.first.wpilibj.TimedRobot;
11
12public class Robot extends TimedRobot {
13  private static double kDt = 0.02;
14
15  private final Joystick m_joystick = new Joystick(1);
16  private final ExampleSmartMotorController m_motor = new ExampleSmartMotorController(1);
17  // Note: These gains are fake, and will have to be tuned for your robot.
18  private final SimpleMotorFeedforward m_feedforward = new SimpleMotorFeedforward(1, 1.5);
19
20  private final TrapezoidProfile.Constraints m_constraints =
21      new TrapezoidProfile.Constraints(1.75, 0.75);
22  private TrapezoidProfile.State m_goal = new TrapezoidProfile.State();
23  private TrapezoidProfile.State m_setpoint = new TrapezoidProfile.State();
24
25  @Override
26  public void robotInit() {
27    // Note: These gains are fake, and will have to be tuned for your robot.
28    m_motor.setPID(1.3, 0.0, 0.7);
29  }
30
31  @Override
32  public void teleopPeriodic() {
33    if (m_joystick.getRawButtonPressed(2)) {
34      m_goal = new TrapezoidProfile.State(5, 0);
35    } else if (m_joystick.getRawButtonPressed(3)) {
36      m_goal = new TrapezoidProfile.State(0, 0);
37    }
38
39    // Create a motion profile with the given maximum velocity and maximum
40    // acceleration constraints for the next setpoint, the desired goal, and the
41    // current setpoint.
42    var profile = new TrapezoidProfile(m_constraints, m_goal, m_setpoint);
43
44    // Retrieve the profiled setpoint for the next timestep. This setpoint moves
45    // toward the goal while obeying the constraints.
46    m_setpoint = profile.calculate(kDt);
47
48    // Send setpoint to offboard controller PID
49    m_motor.setSetpoint(
50        ExampleSmartMotorController.PIDMode.kPosition,
51        m_setpoint.position,
52        m_feedforward.calculate(m_setpoint.velocity) / 12.0);
53  }
54}