Otonom Program Seçimi

Çoğu zaman takımlar ya müsabakayla ilgili sebepler yüzünden ya da yeni yazılım denemek için birden fazla otonom programa sahiptir. Programlar zaman geciktirme, farklı stratejiler vb. özelliklerin eklenmesiyle birbirleri arasında farklılaşmaktadır. Programın çalıştırılması için seçilen yöntemler genellikle anahtarlar, kumanda tuşları, kadranlar veya diğer donanım temelli girdileri içermektedir.

SmartDashboard ile çalıştırmak istediğiniz otonom programı seçmek için sadece ekranda bir araç görüntüleyebilirsiniz. Komut temelli programlardaysa program birkaç komuttan biriyle sarmalanmaktadır. Bu yazı, TimedRobot ve Komut Temelli Robotlara dair örneklerle, nasıl sadece birkaç satır kodla ve hoş bir kullanıcı arayüzüyle otonom bir program seçeceğinizi gösterecektir.

TimedRobot

Not

The code snippets shown below are part of the TimedRobot template (Java, C++):

SendableChooser Nesnesi Oluşturmak

Robot.java / Robot.h’de SendableChooser nesnesine referans verebilecek bir değişken oluşturunuz. İki veya daha fazla otonom mod chooser - seçiciye gönderilecek string’lerin oluşturulmasıyla eklenebilmektedir. SendableChooser ile bu modlardan herhangi biri seçilebilmektedir. Bu örnekte seçenek olarak Default ve My Auto gösterilmektedir. Bunların yanı sıra hangi modun seçildiğini depolayacak bir değişkene, m_autoSelected, de ihtiyacınız olacaktır

  private static final String kDefaultAuto = "Default";
  private static final String kCustomAuto = "My Auto";
  private String m_autoSelected;
  private final SendableChooser<String> m_chooser = new SendableChooser<>();
  frc::SendableChooser<std::string> m_chooser;
  const std::string kAutoNameDefault = "Default";
  const std::string kAutoNameCustom = "My Auto";
  std::string m_autoSelected;
import wpilib
self.defaultAuto = "Default"
self.customAuto = "My Auto";
self.chooser = wpilib.SendableChooser()

Seçeneklerin Kurulumu

Chooser; tanımlı bir öğeler listesinden seçim yapmanıza olanak tanımaktadır, bu durumda öğeler yukarıda tanımladığımız string’lerdir. Robot constructor’ında setDefaultOption veya addOption kullanarak yukarıda string olarak oluşturulmuş seçeneklerinizi ekleyiniz. Gösterge paneli başlatıldığında setDefaultOption varsayılan olarak seçilecektir. putData fonksiyonu seçeneğinizi driver station - sürücü istasyonu bilgisayaranızdaki gösterge paneline yollayacaktır.

  public Robot() {
    m_chooser.setDefaultOption("Default Auto", kDefaultAuto);
    m_chooser.addOption("My Auto", kCustomAuto);
    SmartDashboard.putData("Auto choices", m_chooser);
  }
Robot::Robot() {
  m_chooser.SetDefaultOption(kAutoNameDefault, kAutoNameDefault);
  m_chooser.AddOption(kAutoNameCustom, kAutoNameCustom);
  frc::SmartDashboard::PutData("Auto Modes", &m_chooser);
}
from wpilib import SmartDashboard
self.chooser.setDefaultOption("Default Auto", self.defaultAuto)
self.chooser.addOption("My Auto", self.customAuto)
SmartDashboard.putData("Auto choices", self.chooser)

Otonom Kodun Çalıştırılması

Şimdi, autonomousInit ve autonomousPeriodic’de hangi seçeneğin seçildiğini görmek ve otonom zaman aralığı içerisinde neler olacağını belirlemek için m_autoSelected değişkenini kullanabilirsiniz.

  @Override
  public void autonomousInit() {
    m_autoSelected = m_chooser.getSelected();
    System.out.println("Auto selected: " + m_autoSelected);
  }

  /** This function is called periodically during autonomous. */
  @Override
  public void autonomousPeriodic() {
    switch (m_autoSelected) {
      case kCustomAuto:
        // Put custom auto code here
        break;
      case kDefaultAuto:
      default:
        // Put default auto code here
        break;
    }
  }
void Robot::AutonomousInit() {
  m_autoSelected = m_chooser.GetSelected();
  wpi::print("Auto selected: {}\n", m_autoSelected);

  if (m_autoSelected == kAutoNameCustom) {
    // Custom Auto goes here
  } else {
    // Default Auto goes here
  }
}

void Robot::AutonomousPeriodic() {
  if (m_autoSelected == kAutoNameCustom) {
    // Custom Auto goes here
  } else {
    // Default Auto goes here
  }
}
def autonomousInit(self):
   self.autoSelected = self.chooser.getSelected()
   print("Auto selected: " + self.autoSelected)
def autonomousPeriodic(self):
   match self.autoSelected:
      case self.customAuto:
         # Put custom auto code here
      case _:
         # Put default auto code here

Komut Temelli

Not

The code snippets shown below are part of the HatchbotTraditional example project (Java, C++, Python):

SendableChooser Nesnesinin Oluşturulması

RobotContainer’da SendableChooser nesnesine referans verebilecek bir değişken oluşturunuz. . İki veya daha fazla komut yeni değişkenlerde oluşturulup depolanabilmektedir. SendableChooser ile bu modlardan herhangi biri seçilebilmektedir. Bu örnekte seçenek olarak SimpleAuto ve SimpleAuto gösterilmektedir.

  // A simple auto routine that drives forward a specified distance, and then stops.
  private final Command m_simpleAuto =
      new DriveDistance(
          AutoConstants.kAutoDriveDistanceInches, AutoConstants.kAutoDriveSpeed, m_robotDrive);

  // A complex auto routine that drives forward, drops a hatch, and then drives backward.
  private final Command m_complexAuto = new ComplexAuto(m_robotDrive, m_hatchSubsystem);

  // A chooser for autonomous commands
  SendableChooser<Command> m_chooser = new SendableChooser<>();
  // The autonomous routines
  DriveDistance m_simpleAuto{AutoConstants::kAutoDriveDistanceInches,
                             AutoConstants::kAutoDriveSpeed, &m_drive};
  ComplexAuto m_complexAuto{&m_drive, &m_hatch};

  // The chooser for the autonomous routines
  frc::SendableChooser<frc2::Command*> m_chooser;
  // The autonomous routines
  frc2::CommandPtr m_simpleAuto = autos::SimpleAuto(&m_drive);
  frc2::CommandPtr m_complexAuto = autos::ComplexAuto(&m_drive, &m_hatch);

  // The chooser for the autonomous routines
  frc::SendableChooser<frc2::Command*> m_chooser;
        # A simple auto routine that drives forward a specified distance, and then stops.
        self.simpleAuto = DriveDistance(
            constants.kAutoDriveDistanceInches, constants.kAutoDriveSpeed, self.drive
        )

        # A complex auto routine that drives forward, drops a hatch, and then drives backward.
        self.complexAuto = ComplexAuto(self.drive, self.hatch)

        # Chooser
        self.chooser = wpilib.SendableChooser()

SendableChooser’ın Kurulumu

Aralarından seçim yapabileceğiniz iki otonom programınız olduğunu ve SimpleAuto ile ComplexAuto komutlarının bu programları kapsandığını varsayın. Programlardan birini seçmek için:

RobotContainer’da bir SendableChooser nesnesi oluşturup iki komutun örneklerini bu nesneye ekleyiniz. Komutlar herhangi bir miktarda olabilir ve varsayılan olarak eklenen komut (setDefaultOption), başlangıçta seçilen komut haline gelmektedir. Gördüğünüz üzere her komut SendableChooser örneğinde bir setDefaultOption() veya addOption() metod çağrısına dahil edilmektedir.

    // Add commands to the autonomous command chooser
    m_chooser.setDefaultOption("Simple Auto", m_simpleAuto);
    m_chooser.addOption("Complex Auto", m_complexAuto);
  // Add commands to the autonomous command chooser
  m_chooser.SetDefaultOption("Simple Auto", &m_simpleAuto);
  m_chooser.AddOption("Complex Auto", &m_complexAuto);
  // Add commands to the autonomous command chooser
  // Note that we do *not* move ownership into the chooser
  m_chooser.SetDefaultOption("Simple Auto", m_simpleAuto.get());
  m_chooser.AddOption("Complex Auto", m_complexAuto.get());
        # Add commands to the autonomous command chooser
        self.chooser.setDefaultOption("Simple Auto", self.simpleAuto)
        self.chooser.addOption("Complex Auto", self.complexAuto)

Ardından chooser’ı gösterge paneline yayınlayınız:

// Put the chooser on the dashboard
SmartDashboard.putData(m_chooser);
// Put the chooser on the dashboard
frc::SmartDashboard::PutData(&m_chooser);
from wpilib import SmartDashboard
# Put the chooser on the dashboard
SmartDashboard.putData(chooser)

Otonom Komutun Başlatılması

In Robot.java, when the autonomous period starts, the SendableChooser object is polled to get the selected command and that command must be scheduled.

  public Command getAutonomousCommand() {
    return m_chooser.getSelected();
  }
  public void autonomousInit() {
    m_autonomousCommand = m_robotContainer.getAutonomousCommand();

    // schedule the autonomous command (example)
    if (m_autonomousCommand != null) {
      m_autonomousCommand.schedule();
    }
  }
frc2::Command* RobotContainer::GetAutonomousCommand() {
  // Runs the chosen command in autonomous
  return m_chooser.GetSelected();
}
void Robot::AutonomousInit() {
  m_autonomousCommand = m_container.GetAutonomousCommand();

  if (m_autonomousCommand != nullptr) {
    m_autonomousCommand->Schedule();
  }
}
    def getAutonomousCommand(self) -> commands2.Command:
        return self.chooser.getSelected()
    def autonomousInit(self) -> None:
        """This autonomous runs the autonomous command selected by your RobotContainer class."""
        self.autonomousCommand = self.container.getAutonomousCommand()

        if self.autonomousCommand:
            self.autonomousCommand.schedule()

Otonom sırasında Zamanlayıcının Çalıştırılması

Robot.java için bu komut her driver station güncelleme aralığında (yaklaşık her 20ms’de bir) zamanlayıcıyı çalıştıracak ve seçilen otonom komutun başlatılmasını sağlayacaktır. Python’da zamanlayıcı TimedCommandRobot her kullanıldığında kendiliğinden çalışmaktadır.

Not

Zamanlayıcının çalıştırılması autonomousPeriodic() veya robotPeriodic() fonksiyonunda gerçekleşebilmektedir, her ikisi de otonom modda benzer işlevler görecektir.

49  @Override
50  public void robotPeriodic() {
51    CommandScheduler.getInstance().run();
52  }
29void Robot::RobotPeriodic() {
30  frc2::CommandScheduler::GetInstance().Run();
31}

Otonom Komutun İptal Edilmesi

Robot.java’da teleop dönemi başladığında otonom komut iptal edilecektir.

87  @Override
88  public void teleopInit() {
89    // This makes sure that the autonomous stops running when
90    // teleop starts running. If you want the autonomous to
91    // continue until interrupted by another command, remove
92    // this line or comment it out.
93    if (m_autonomousCommand != null) {
94      m_autonomousCommand.cancel();
95    }
96  }
56void Robot::TeleopInit() {
57  // This makes sure that the autonomous stops running when
58  // teleop starts running. If you want the autonomous to
59  // continue until interrupted by another command, remove
60  // this line or comment it out.
61  if (m_autonomousCommand != nullptr) {
62    m_autonomousCommand->Cancel();
63    m_autonomousCommand = nullptr;
64  }
65}
51    def teleopInit(self) -> None:
52        # This makes sure that the autonomous stops running when
53        # teleop starts running. If you want the autonomous to
54        # continue until interrupted by another command, remove
55        # this line or comment it out.
56        if self.autonomousCommand:
57            self.autonomousCommand.cancel()

SmartDashboard Ekranı

SendableChooser seçilebilecek iki otonom mod göstermektedir: Simple Auto - Basit Otonom ve Complex Auto - Karmaşık Otonom

When the SmartDashboard is run, the choices from the SendableChooser are automatically displayed. You can simply pick an option before the autonomous period begins and the corresponding command will run.