Sorun giderme

Tam Arızaların Giderilmesi

Robotunuzun tamamen yanlış bir şey yapmasına neden olabilecek birkaç şey vardır. Aşağıdaki kontrol listesi bazı yaygın hataları kapsamaktadır.

  • Robotum hareket etmiyor.

    • Gerçekten motorlarınıza çıktı mı veriyorsunuz?

    • Sürücü istasyonuna bir MalformedSplineException yazdırılıyor mu? Evet ise, aşağıdaki MalformedSplineException bölümüne gidin.

    • Yörüngeniz çok kısa mı yoksa yanlış birimlerde mi?

  • Robotum, yörüngeyi diğer yöne bakacak şekilde sürmek için dönüyor.

    • Yörüngenizin başlangıç ve bitiş yörüngeleri yanlış mı?

    • Robotunuzun jiroskopu yanlış yöne mi sıfırlanıyor?

    • Ters bayrağı yanlış mı ayarlanmış?

    • Gyro açılarınız saat yönünde pozitif mi? Eğer öyleyse, onları reddetmelisiniz.

  • Robotum dönmesi gerekmesine rağmen sadece düz bir çizgide ilerliyor.

    • Gyro’nuz doğru bir şekilde kurulmuş ve iyi veriler döndürüyor mu?

    • Gyro başlığınızı odometri nesnenize doğru birimlerle mi geçiriyorsunuz?

    • İz genişliğiniz doğru mu? Doğru birimlerde mi?

  • Sürücü istasyonunda bir MalformedSplineException çıktısı alıyorum ve robot hareket etmiyor.

    • Ters bayrağı yanlış mı ayarlanmış?

    • Yaklaşık olarak zıt başlıklarla birbirine çok yakın iki ara noktanız var mı?

    • Aynı (veya neredeyse aynı) koordinatlara sahip iki ara noktanız var mı?

  • Robotum çok uzağa gidiyor.

    • Kodlayıcı birimi dönüştürmeleriniz doğru ayarlanmış mı?

    • Kodlayıcılarınız bağlı mı?

  • Robotum çoğunlukla doğru olanı yapıyor, ancak biraz yanlış.

    • Sonraki bölüme gidin.

Kötü Performans Sorunlarını Giderme

Not

Bu bölüm çoğunlukla, derleme hataları, dönen ve yanlış yöne giden robotlar veya MalformedSplineException lar gibi yıkıcı arızalar değil, bir metre hata gibi zayıf yörünge izleme performansının giderilmesiyle ilgilidir.

Not

Bu bölüm diferansiyel tahrikli robotlar için tasarlanmıştır, ancak fikirlerin çoğu swerve veya mecanum sürüşü yönlendirmek için uyarlanabilir.

Zayıf yörünge izleme performansının giderilmesi zor olabilir. Yörünge oluşturucu ve takipçinin kullanımı kolay ve kutudan çıkar çıkmaz performans göstermesi amaçlansa da, robotunuzun olması gerektiği yere tam olarak varmadığı durumlar vardır. Yörünge oluşturucu ve takipçilerin ayarlanması gereken çok sayıda düğmesi ve birçok hareketli parçası vardır, bu nedenle, özellikle robotun genel davranışından yörünge sorunlarının kaynağını bulmak zor olduğu için nereden başlayacağını bilmek zor olabilir.

Yörünge oluşturucu katmanını ve hatalı davranan takipçileri bulmak çok zor olabileceğinden, genel olarak kötü izleme performansı için sistematik, katman katman bir yaklaşım önerilir (örneğin, robot birkaç feet veya yirmi dereceden fazla uzakta) . Aşağıdaki adımlar, yapmanız gereken sıraya göre listelenmiştir; Farklı adımların etkilerini birbirinden ayırabilmeniz için bu sırayı takip etmeniz önemlidir.

Not

The below examples put diagnostic values onto NetworkTables. The easiest way to graph these values is to use Shuffleboard’s graphing capabilities.

Odometriyi Doğrula

Odometreniz kötüyse, Ramsete kontrol cihazınız yanlış davranabilir, çünkü robotunuzun hedef hızlarını, odometrenizin robotun nerede olduğunu düşündüğüne bağlı olarak değiştirir.

Not

Sending your robot pose and trajectory to field2d can help verify that your robot is driving correctly relative to the robot trajectory.

  1. Her odometre güncellemesinden sonra robotunuzun konumunu kaydetmek için kodunuzu ayarlayın:

NetworkTableEntry m_xEntry = NetworkTableInstance.getDefault().getTable("troubleshooting").getEntry("X");
NetworkTableEntry m_yEntry = NetworkTableInstance.getDefault().getTable("troubleshooting").getEntry("Y");

@Override
public void periodic() {
    // Update the odometry in the periodic block
    m_odometry.update(Rotation2d.fromDegrees(getHeading()), m_leftEncoder.getDistance(),
        m_rightEncoder.getDistance());

    var translation = m_odometry.getPoseMeters().getTranslation();
    m_xEntry.setNumber(translation.getX());
    m_yEntry.setNumber(translation.getY());
}
NetworkTableEntry m_xEntry = nt::NetworkTableInstance::GetDefault().GetTable("troubleshooting")->GetEntry("X");
NetworkTableEntry m_yEntry = nt::NetworkTableInstance::GetDefault().GetTable("troubleshooting")->GetEntry("Y");

void DriveSubsystem::Periodic() {
    // Implementation of subsystem periodic method goes here.
    m_odometry.Update(frc::Rotation2d(units::degree_t(GetHeading())),
                        units::meter_t(m_leftEncoder.GetDistance()),
                        units::meter_t(m_rightEncoder.GetDistance()));

    auto translation = m_odometry.GetPose().Translation();
    m_xEntry.SetDouble(translation.X().value());
    m_yEntry.SetDouble(translation.Y().value());
}
  1. Robotunuza paralel bir mezura yerleştirin ve robotunuzu şerit metre boyunca yaklaşık bir metre dışarı doğru itin. Y ekseni boyunca bir şerit metre yerleştirin ve baştan başlayın, robotunuzu X ekseni boyunca bir metre ve Y ekseni boyunca bir metre kaba bir yay çizerek itin.

  2. Compare X and Y reported by the robot to actual X and Y. If X is off by more than 5 centimeters in the first test then you should check that you measured your wheel diameter correctly, and that your wheels are not worn down. If the second test is off by more than 5 centimeters in either X or Y then your track width (distance from the center of the left wheel to the center of the right wheel) may be incorrect; if you’re sure that you measured the track width correctly with a tape measure then your robot’s wheels may be slipping in a way that is not accounted for by track width, so try increasing the track width number or measuring it programmatically.

Feedforward - ileribesleme’yi Doğrula

İleri beslemeniz kötüyse, robotun her iki tarafındaki P denetleyicileri de takip etmeyecek ve DifferentialDriveVoltageConstraint, robotunuzun hızlanmasını doğru bir şekilde sınırlamayacaktır. İleriye doğru ilerlemeyi izole edip test edebilmek için çoğunlukla tekerlek P kontrol cihazlarını kapatmak istiyoruz.

  1. İlk olarak, her tekerlek için P kontrolörünü devre dışı bırakmalıyız. Her kontrolör için P kazancını 0’a ayarlayın. RamseteCommand örneğinde, kPDriveVel değerini 0 olarak ayarlarsınız:

123            new PIDController(DriveConstants.kPDriveVel, 0, 0),
124            new PIDController(DriveConstants.kPDriveVel, 0, 0),
81      frc::PIDController{DriveConstants::kPDriveVel, 0, 0},
82      frc::PIDController{DriveConstants::kPDriveVel, 0, 0},
  1. Next, we want to disable the Ramsete controller to make it easier to isolate our problematic behavior. To do so, simply call setEnabled(false) on the RamseteController passed into your RamseteCommand:

RamseteController m_disabledRamsete = new RamseteController();
m_disabledRamsete.setEnabled(false);

// Be sure to pass your new disabledRamsete variable
RamseteCommand ramseteCommand = new RamseteCommand(
    exampleTrajectory,
    m_robotDrive::getPose,
    m_disabledRamsete,
    ...
);
frc::RamseteController m_disabledRamsete;
m_disabledRamsete.SetEnabled(false);

// Be sure to pass your new disabledRamsete variable
frc2::RamseteCommand ramseteCommand(
  exampleTrajectory,
  [this]() { return m_drive.GetPose(); },
  m_disabledRamsete,
  ...
);
  1. Son olarak, istenen tekerlek hızını ve gerçek tekerlek hızını kaydetmemiz gerekir (Shuffleboard kullanıyorsanız veya grafik yazılımınız bu özelliğe sahipse, gerçek ve istenen hızları aynı grafiğe koymalısınız):

var table = NetworkTableInstance.getDefault().getTable("troubleshooting");
var leftReference = table.getEntry("left_reference");
var leftMeasurement = table.getEntry("left_measurement");
var rightReference = table.getEntry("right_reference");
var rightMeasurement = table.getEntry("right_measurement");

var leftController = new PIDController(kPDriveVel, 0, 0);
var rightController = new PIDController(kPDriveVel, 0, 0);
RamseteCommand ramseteCommand = new RamseteCommand(
    exampleTrajectory,
    m_robotDrive::getPose,
    disabledRamsete, // Pass in disabledRamsete here
    new SimpleMotorFeedforward(ksVolts, kvVoltSecondsPerMeter, kaVoltSecondsSquaredPerMeter),
    kDriveKinematics,
    m_robotDrive::getWheelSpeeds,
    leftController,
    rightController,
    // RamseteCommand passes volts to the callback
    (leftVolts, rightVolts) -> {
        m_robotDrive.tankDriveVolts(leftVolts, rightVolts);

        leftMeasurement.setNumber(m_robotDrive.getWheelSpeeds().leftMetersPerSecond);
        leftReference.setNumber(leftController.getSetpoint());

        rightMeasurement.setNumber(m_robotDrive.getWheelSpeeds().rightMetersPerSecond);
        rightReference.setNumber(rightController.getSetpoint());
    },
    m_robotDrive
);
auto table =
    nt::NetworkTableInstance::GetDefault().GetTable("troubleshooting");
auto leftRef = table->GetEntry("left_reference");
auto leftMeas = table->GetEntry("left_measurement");
auto rightRef = table->GetEntry("right_reference");
auto rightMeas = table->GetEntry("right_measurement");

frc::PIDController leftController(DriveConstants::kPDriveVel, 0, 0);
frc::PIDController rightController(DriveConstants::kPDriveVel, 0, 0);
frc2::RamseteCommand ramseteCommand(
    exampleTrajectory, [this]() { return m_drive.GetPose(); },
    frc::RamseteController(AutoConstants::kRamseteB,
                            AutoConstants::kRamseteZeta),
    frc::SimpleMotorFeedforward<units::meters>(
        DriveConstants::ks, DriveConstants::kv, DriveConstants::ka),
    DriveConstants::kDriveKinematics,
    [this] { return m_drive.GetWheelSpeeds(); }, leftController,
    rightController,
    [=](auto left, auto right) {
        auto leftReference = leftRef;
        auto leftMeasurement = leftMeas;
        auto rightReference = rightRef;
        auto rightMeasurement = rightMeas;

        m_drive.TankDriveVolts(left, right);

        leftMeasurement.SetDouble(m_drive.GetWheelSpeeds().left.value());
        leftReference.SetDouble(leftController.GetSetpoint());

        rightMeasurement.SetDouble(m_drive.GetWheelSpeeds().right.value());
        rightReference.SetDouble(rightController.GetSetpoint());
    },
    {&m_drive});
  1. Run the robot on a variety of trajectories (curved and straight line), and check to see if the actual velocity tracks the desired velocity by looking at graphs from NetworkTables.

  2. If the desired and actual are off by a lot then you should check if the wheel diameter and encoderEPR you used for system identification were correct. If you’ve verified that your units and conversions are correct, then you should try recharacterizing on the same floor that you’re testing on to see if you can get better data.

P Kazancını Doğrula

Önceki adımı tamamladıysanız ve sorun ortadan kalktıysa, sorununuz muhtemelen sonraki adımlardan birinde bulunabilir. Bu adımda, tekerlek P kontrol cihazlarınızın iyi ayarlanmış olduğunu doğrulayacağız. Java kullanıyorsanız, Ramsete’yi kapatmak istiyoruz, böylece PF denetleyicilerimizi kendi başlarına görüntüleyebilelim.

  1. **P kazancının önceki sıfır olmayan değere ayarlanması dışında **, gerçek ve istenen hızı (ve Java kullanıyorsanız Ramsete’yi devre dışı bırakan kodu) günlüğe kaydeden önceki adımdaki tüm kodu tekrar kullanmanız gerekir.

  2. Robotu çeşitli yörüngelerde tekrar çalıştırın ve gerçek ve istenen grafiklerin iyi göründüğünü kontrol edin.

  3. Grafikler iyi görünmüyorsa (yani gerçek hız, istenenden çok farklıysa), P kazancınızı ayarlamayı ve test yörüngelerini yeniden çalıştırmayı denemelisiniz.

Kısıtlamaları Kontrol Et

Not

Bu adım için P kazancınızın sıfır olmadığından ve önceki adımlarda eklenen günlük kodunun hala bulunduğundan emin olun. Java kullanıyorsanız, Ramsete’yi devre dışı bırakmak için kodu kaldırmalısınız.

Doğruluk sorununuz önceki adımların tümünde devam ettiyse, kısıtlamalarınızla ilgili bir sorununuz olabilir. Aşağıda, farklı mevcut kısıtlamaların yetersiz ayarlandığında göstereceği belirtilerin bir listesi bulunmaktadır.

Her seferinde bir kısıtlamayı test edin! Diğer kısıtlamaları kaldırın, kalan kısıtlamalardan birini ayarlayın ve kullanmak istediğiniz her kısıtlama için bu işlemi tekrarlayın. Aşağıdaki kontrol listesi, bir seferde yalnızca bir kısıtlama kullandığınızı varsayar.

  • DifferentialDriveVoltageConstraint:

    • Robotunuz çok yavaş hızlanırsa, bu kısıtlama için maksimum voltajın çok düşük olması mümkündür.

    • If your robot doesn’t reach the end of the path then your system identification data may problematic.

  • DifferentialDriveKinematicsConstraint:

    • Robotunuz yanlış istikamette biterse, maksimum aktarma organı yan hızının çok düşük veya çok yüksek olması mümkündür. Bunu söylemenin tek yolu maksimum hızı ayarlamak ve ne olacağını görmektir.

  • CentripetalAccelerationConstraint:

    • Robotunuz yanlış istikamette biterse, suçlu bu olabilir. Robotunuz yeterince dönmüyorsa, maksimum merkezcil ivmeyi artırmalısınız, ancak hızlı dönüşler hızla dönüyorsa, maksimum merkezcil ivmeyi-maximum centripetal azaltmalısınız.

Yörünge Yol Noktalarını Kontrol Edin

Yörüngenizin kendisinin pek sürülebilir olmaması mümkündür. Keskin dönüşleri azaltmak için ara noktaları (ve varsa ara noktalardaki yönleri) hareket ettirmeyi deneyin.