Définition des préférences du robot

The Robot Preferences (Java, C++) class is used to store values in the flash memory on the roboRIO. The values might be for remembering preferences on the robot such as calibration settings for potentiometers, PID values, setpoints, etc. that you would like to change without having to rebuild the program. The values can be viewed on SmartDashboard or Shuffleboard and read and written by the robot program.

Cet exemple montre comment utiliser les Préférences pour modifier le point de consigne d’un régulateur PID et la constante P. Les exemples de code sont adaptés de l’exemple Arm Simulation (Java, C++). Vous pouvez exécuter l’exemple de simulation de bras dans le simulateur de robot pour voir comment utiliser la classe de préférences et interagir avec elle à l’aide des tableaux de bord sans avoir besoin d’un robot.

Initialisation des préférences

  public static final String kArmPositionKey = "ArmPosition";
  public static final String kArmPKey = "ArmP";

  // The P gain for the PID controller that drives this arm.
  public static final double kDefaultArmKp = 50.0;
  public static final double kDefaultArmSetpointDegrees = 75.0;
  // The P gain for the PID controller that drives this arm.
  private double m_armKp = Constants.kDefaultArmKp;
  private double m_armSetpointDegrees = Constants.kDefaultArmSetpointDegrees;
  public Arm() {
    m_encoder.setDistancePerPulse(Constants.kArmEncoderDistPerPulse);
    // Set the Arm position setpoint and P constant to Preferences if the keys don't already exist
    Preferences.initDouble(Constants.kArmPositionKey, m_armSetpointDegrees);
    Preferences.initDouble(Constants.kArmPKey, m_armKp);
  }
inline constexpr std::string_view kArmPositionKey = "ArmPosition";
inline constexpr std::string_view kArmPKey = "ArmP";

inline constexpr double kDefaultArmKp = 50.0;
inline constexpr units::degree_t kDefaultArmSetpoint = 75.0_deg;
Arm::Arm() {
  // Set the Arm position setpoint and P constant to Preferences if the keys
  // don't already exist
  frc::Preferences::InitDouble(kArmPositionKey, m_armSetpoint.value());
  frc::Preferences::InitDouble(kArmPKey, m_armKp);
}
    kArmPositionKey = "ArmPosition"
    kArmPKey = "ArmP"

    # The P gain for the PID controller that drives this arm.
    kDefaultArmKp = 50.0
    kDefaultArmSetpointDegrees = 75.0
        # The P gain for the PID controller that drives this arm.
        self.armKp = Constants.kDefaultArmKp
        self.armSetpointDegrees = Constants.kDefaultArmSetpointDegrees

        # Set the Arm position setpoint and P constant to Preferences if the keys don't already exist
        wpilib.Preferences.initDouble(
            Constants.kArmPositionKey, self.armSetpointDegrees
        )
        wpilib.Preferences.initDouble(Constants.kArmPKey, self.armKp)

Les préférences sont stockées sous un nom, la clé. Il est utile de stocker la clé dans une constante, comme kArmPositionKey et kArmPKey dans le code ci-dessus pour éviter de la taper plusieurs fois et d’éviter les fautes de frappe. Nous déclarons également des variables, kArmKp et armPositionDeg pour contenir les données récupérées à partir des préférences.

Dans robotInit, chaque clé est vérifiée pour voir si elle existe déjà dans la base de données des Préférences. La méthode containsKey prend un paramètre, la clé pour vérifier si les données pour cette clé existent déjà dans la base de données des préférences. S’il n’existe pas, une valeur par défaut est écrite. La méthode setDouble prend deux paramètres, la clé à écrire et les données à écrire. Il existe des méthodes similaires pour d’autres types de données comme les booléens, les entiers et les chaînes.

Si vous utilisez Command Framework, ce type de code peut être placé dans le constructeur d’un sous-système ou d’une commande.

Préférences de lecture

  public void loadPreferences() {
    // Read Preferences for Arm setpoint and kP on entering Teleop
    m_armSetpointDegrees = Preferences.getDouble(Constants.kArmPositionKey, m_armSetpointDegrees);
    if (m_armKp != Preferences.getDouble(Constants.kArmPKey, m_armKp)) {
      m_armKp = Preferences.getDouble(Constants.kArmPKey, m_armKp);
      m_controller.setP(m_armKp);
    }
  }
void Arm::LoadPreferences() {
  // Read Preferences for Arm setpoint and kP on entering Teleop
  m_armSetpoint = units::degree_t{
      frc::Preferences::GetDouble(kArmPositionKey, m_armSetpoint.value())};
  if (m_armKp != frc::Preferences::GetDouble(kArmPKey, m_armKp)) {
    m_armKp = frc::Preferences::GetDouble(kArmPKey, m_armKp);
    m_controller.SetP(m_armKp);
  }
}
    def loadPreferences(self):
        # Read Preferences for Arm setpoint and kP on entering Teleop
        self.armSetpointDegrees = wpilib.Preferences.getDouble(
            Constants.kArmPositionKey, self.armSetpointDegrees
        )
        if self.armKp != wpilib.Preferences.getDouble(Constants.kArmPKey, self.armKp):
            self.armKp = wpilib.Preferences.getDouble(Constants.kArmPKey, self.armKp)
            self.controller.setP(self.armKp)

Reading a preference is easy. The getDouble method takes two parameters, the key to read, and a default value to use in case the preference doesn’t exist. There are similar methods for other data types like booleans, ints, and strings.

Selon les données stockées dans les préférences, vous pouvez les utiliser lorsque vous les lisez, comme la constante proportionnelle ci-dessus. Ou vous pouvez le stocker dans une variable et l’utiliser plus tard, comme le point de consigne, qui est utilisé dans telopPeriodic ci-dessous.

  @Override
  public void teleopPeriodic() {
    if (m_joystick.getTrigger()) {
      // Here, we run PID control like normal.
      m_arm.reachSetpoint();
    } else {
      // Otherwise, we disable the motor.
      m_arm.stop();
    }
  }
  /** Run the control loop to reach and maintain the setpoint from the preferences. */
  public void reachSetpoint() {
    var pidOutput =
        m_controller.calculate(
            m_encoder.getDistance(), Units.degreesToRadians(m_armSetpointDegrees));
    m_motor.setVoltage(pidOutput);
  }
void Robot::TeleopPeriodic() {
  if (m_joystick.GetTrigger()) {
    // Here, we run PID control like normal.
    m_arm.ReachSetpoint();
  } else {
    // Otherwise, we disable the motor.
    m_arm.Stop();
  }
}
void Arm::ReachSetpoint() {
  // Here, we run PID control like normal, with a setpoint read from
  // preferences in degrees.
  double pidOutput = m_controller.Calculate(
      m_encoder.GetDistance(), (units::radian_t{m_armSetpoint}.value()));
  m_motor.SetVoltage(units::volt_t{pidOutput});
}
    def teleopPeriodic(self):
        if self.joystick.getTrigger():
            # Here, we run PID control like normal.
            self.arm.reachSetpoint()
        else:
            # Otherwise, we disable the motor.
            self.arm.stop()
    def reachSetpoint(self):
        pidOutput = self.controller.calculate(
            self.encoder.getDistance(),
            units.degreesToRadians(self.armSetpointDegrees),
        )
        self.motor.setVoltage(pidOutput)

Utilisation des préférences dans SmartDashboard

Affichage des préférences dans SmartDashboard

Ajout de préférences depuis le menu Smartdashboard

Dans le SmartDashboard, l’affichage des Préférences peut être ajouté à l’affichage en sélectionnant View puis Add… puis Robot Preferences. Cela révèle le contenu du fichier de préférences stocké dans la mémoire flash du roboRIO.

Modification des préférences dans SmartDashboard

Modification des préférences du robot via le widget SmartDashboard.

Les valeurs sont affichées ici avec les valeurs par défaut du code. Si les valeurs doivent être ajustées, elles peuvent être modifiées ici et enregistrées.

Utilisation des préférences dans Shuffleboard

Affichage des préférences dans Shuffleboard

Ajout de préférences à partir de la fenêtre des sources dans Shuffleboard

Dans Shuffleboard, l’affichage des Préférences peut être ajouté à l’affichage en faisant glisser le champ des préférences depuis la fenêtre des sources. Cela révèle le contenu du fichier de préférences stocké dans la mémoire flash du roboRIO.

Modification des préférences dans Shuffleboard

Modification des préférences du robot via le widget Shuffleboard.

Les valeurs sont affichées ici avec les valeurs par défaut du code. Si les valeurs doivent être ajustées, elles peuvent être modifiées ici.