WPILib ile Fizik Simülasyonu

Çünkü durum-uzay gösterimi , :systems ‘in dynamics kompakt bir şekilde temsil etmemize olanak tanır, robotlarda fiziksel sistemleri simüle etmek için onu kullanabiliriz. Bu simülatörlerin amacı, mevcut simülasyon dışı kullanıcı kodunu değiştirmeden robot mekanizmalarının hareketini simüle etmektir. Bu tür simülatörlerin temel akışı aşağıdaki gibidir:

  • Normal kullanıcı kodunda:

    • PID veya benzer kontrol algoritmaları, kodlayıcı (veya diğer sensör) okumalarından voltaj komutları üretir

    • Motor çıkışları ayarlandı

  • Simülasyon periyodik kodunda:

    • Simülasyonun state`i, :term:`inputs genellikle bir PID döngüsünden ayarlanmış motorlardan gelen voltajlar kullanılarak güncellenir.

    • Simüle edilmiş kodlayıcı (veya diğer sensör) okumaları, sonraki zaman adımında kullanıcı kodunun kullanılması için ayarlanır

WPILib’in Simülasyon Sınıfları

WPILib’de aşağıdaki fizik simülasyon sınıfları mevcuttur:

  • Doğrusal dinamikli sistemleri modellemek için LinearSystemSim,

  • FlywheelSim - Volan Sim

  • DiferansiyelDrivetrainSim

  • Yerçekimini modelleyen ElevatorSim

  • Yerçekimini modelleyen SingleJointedArmSim

  • Akü voltajı düşüşünü çekilen akımlara göre tahmin eden BatterySim

Tüm simülasyon sınıfları (diferansiyel sürücü simülatörü haricinde) LinearSystemSim sınıfından miras alır. Varsayılan olarak, dinamikler doğrusal sistem dinamikleridir \(\mathbf{x}_{k+1} = \mathbf{A}\mathbf{x}_k + \mathbf{B}\mathbf{u}_k\) . Alt sınıflar UpdateX(x, u, dt) gibi methorları, yerçekimi modelleme, özel ve doğrusal olmayan dinamikler sağlamak için yöntemini geçersiz kılar.

Kullanıcı Kodunda Kullanım

Aşağıdakiler WPILib’den edinilebilir elevatorsimulation example project.

Motorlar ve kodlayıcılar gibi standart nesnelere ek olarak, asansör simülatörümüzü taşıma kütlesi ve dişli azaltma gibi bilinen sabitleri kullanarak somutlaştırıyoruz. Ayrıca: code: Encoder tarafından okunan mesafeyi ve oranı ayarlayan bir Encoder oluşturuyoruz.

Aşağıdaki örnekte, hareketli taşıyıcının kütlesi (kilogram cinsinden), asansörü tahrik eden tamburun yarıçapı (metre cinsinden), giriş üzerinden çıkış olarak motor ve tambur arasındaki dişli azalması (genellikle birden daha büyüktür) ile verilen bir asansörü simüle ediyoruz, asansörün minimum ve maksimum yüksekliği (metre cinsinden) ve konum tahminimize eklenecek bazı rastgele gürültü.

Not

Asansör ve kol simülatörleri, simüle edilmiş konumun verilen minimum veya maksimum yükseklik veya açıları aşmasını önleyecektir. Sonsuz dönme veya harekete sahip bir mekanizmayı simüle etmek istiyorsanız, LinearSystemSim daha iyi bir seçenek olabilir.

36
37
38
39
40
41
42
43
  private final ElevatorSim m_elevatorSim = new ElevatorSim(m_elevatorGearbox,
      kElevatorGearing,
      kCarriageMass,
      kElevatorDrumRadius,
      kMinElevatorHeight,
      kMaxElevatorHeight,
      VecBuilder.fill(0.01));
  private final EncoderSim m_encoderSim = new EncoderSim(m_encoder);

Daha sonra, teleopPeriodic/TeleopPeriodic (Java/C++), asansörümüzü yerden 30 inç yükseklikte bir ayar noktasına götürmek için basit bir PID kontrol döngüsü kullanır.

36
37
38
39
40
41
42
43
44
45
46
  @Override
  public void teleopPeriodic() {
    if (m_joystick.getTrigger()) {
      // Here, we run PID control like normal, with a constant setpoint of 30in.
      double pidOutput = m_controller.calculate(m_encoder.getDistance(), Units.inchesToMeters(30));
      m_motor.setVoltage(pidOutput);
    } else {
      // Otherwise, we disable the motor.
      m_motor.set(0.0);
    }
  }

Daha sonra, simulationPeriodic/SimulationPeriodic (Java/C++), asansörün simüle edilmiş konumunu güncellemek için motora uygulanan gerilimi kullanır. Sadece simüle edilmiş robotlar için periyodik olarak çalıştığı için SimulationPeriodic kullanıyoruz. Bu, simülasyon kodumuzun gerçek bir robot üzerinde çalıştırılmayacağı anlamına gelir.

Son olarak, simüle edilmiş kodlayıcının mesafe okuması, simüle edilmiş asansörün konumu kullanılarak ayarlanır ve robotun pil voltajı, asansör tarafından çekilen tahmini akımı kullanılarak ayarlanır.

68
69
70
71
72
73
74
75
76
77
78
79
80
81
  @Override
  public void simulationPeriodic() {
    // In this method, we update our simulation of what our elevator is doing
    // First, we set our "inputs" (voltages)
    m_elevatorSim.setInput(m_motor.get() * RobotController.getBatteryVoltage());

    // Next, we update it. The standard loop time is 20ms.
    m_elevatorSim.update(0.020);

    // Finally, we set our simulated encoder's readings and simulated battery voltage
    m_encoderSim.setDistance(m_elevatorSim.getPositionMeters());
    // SimBattery estimates loaded battery voltages
    RoboRioSim.setVInVoltage(BatterySim.calculateDefaultBatteryLoadedVoltage(m_elevatorSim.getCurrentDrawAmps()));
  }