Conception de vos propres classes Sendable

Since the Sendable interface only has one method, writing your own classes that implement Sendable (and thus automatically log values to and/or consume values from the dashboard) is extremely easy: just provide an implementation for the overridable initSendable method, in which setters and getters for your class’s fields are declaratively bound to key values (their display names on the dashboard).

Voici, par exemple, voici l’implémentation de initSendable de l’interface à BangBangController de la WPILib:

151  @Override
152  public void initSendable(SendableBuilder builder) {
153    builder.setSmartDashboardType("BangBangController");
154    builder.addDoubleProperty("tolerance", this::getTolerance, this::setTolerance);
155    builder.addDoubleProperty("setpoint", this::getSetpoint, this::setSetpoint);
156    builder.addDoubleProperty("measurement", this::getMeasurement, null);
157    builder.addDoubleProperty("error", this::getError, null);
158    builder.addBooleanProperty("atSetpoint", this::atSetpoint, null);
159  }
55void BangBangController::InitSendable(wpi::SendableBuilder& builder) {
56  builder.SetSmartDashboardType("BangBangController");
57  builder.AddDoubleProperty(
58      "tolerance", [this] { return GetTolerance(); },
59      [this](double tolerance) { SetTolerance(tolerance); });
60  builder.AddDoubleProperty(
61      "setpoint", [this] { return GetSetpoint(); },
62      [this](double setpoint) { SetSetpoint(setpoint); });
63  builder.AddDoubleProperty(
64      "measurement", [this] { return GetMeasurement(); }, nullptr);
65  builder.AddDoubleProperty(
66      "error", [this] { return GetError(); }, nullptr);
67  builder.AddBooleanProperty(
68      "atSetpoint", [this] { return AtSetpoint(); }, nullptr);
69}

Pour permettre la mise à jour automatique des valeurs par la WPILib « en arrière-plan », les noms de données Sendable sont liés à des méthodes getter et setter plutôt qu’à des valeurs de données spécifiques. Si un champ que vous souhaitez consigner n’a pas de setters et de getters définis, ils peuvent être définis inline à l’aide d’une expression lambda.

La classe SendableBuilder

As seen above, the initSendable method takes a single parameter, builder, of type SendableBuilder (Java, C++, Python). This builder exposes methods that allow binding of getters and setters to dashboard names, as well as methods for safely ensuring that values consumed from the dashboard do not cause unsafe robot behavior.

Liaison des données à l’aide des méthodes addProperty

Comme dans tout code d’un dashboard de la WPILib, les champs Sendable sont en fin de compte transmis via les NetworkTables, et donc les méthodes de liaison de données fournies par SendableBuilder correspondent aux types de données NetworkTables pris en charge:

  • boolean: addBooleanProperty

  • boolean[]: addBooleanArrayProperty

  • double: addDoubleProperty

  • double[]: addDoubleArrayProperty

  • string: addStringProperty

  • string[]: addStringArrayProperty

  • byte[]: addRawProperty

Assurer la sécurité avec setSafeState et setActuator

Étant donné que Sendable permet aux utilisateurs de consommer des valeurs arbitraires lues du dashboard, il est possible pour les utilisateurs de diriger les commandes du dashboard directement vers les actionneurs du robot. Cette opération est extrêmement dangereuse si elle n’est pas faite avec soin; Les dashboards ne sont pas une interface particulièrement efficace pour contrôler les mouvements du robot, et les utilisateurs ne s’attendent généralement pas à ce que le robot se déplace en réponse à un changement effectué à partir de valeur sur le dashboard.

Pour aider les utilisateurs à s’assurer d’une interfaçage sécuritaire avec les valeurs du dashboard, SendableBuilder expose une méthode setSafeState, qui est appelée pour placer tout mécanisme Sendable qui s’active en fonction d’une entrée du dashboard dans un état sécuritaire. Toute implémentation Sendable potentiellement dangereuse programmée par un utilisateur doit appeler setSafeState avec une implémentation d’état sécuritaire appropriée. Voici, par exemple, l’implémentation de la classe WPILib PWMMotorController:

120  @Override
121  public void initSendable(SendableBuilder builder) {
122    builder.setSmartDashboardType("Motor Controller");
123    builder.setActuator(true);
124    builder.setSafeState(this::disable);
125    builder.addDoubleProperty("Value", this::get, this::set);
126  }
56void PWMMotorController::InitSendable(wpi::SendableBuilder& builder) {
57  builder.SetSmartDashboardType("Motor Controller");
58  builder.SetActuator(true);
59  builder.SetSafeState([=, this] { Disable(); });
60  builder.AddDoubleProperty(
61      "Value", [=, this] { return Get(); },
62      [=, this](double value) { Set(value); });

En outre, les utilisateurs peuvent appeler builder.setActuator(true) pour marquer tout mécanisme qui pourrait se déplacer à la suite de l’entrée Sendable en tant qu’actionneur. Actuellement, il est utilisé par Shuffleboard pour désactiver les widgets d’actionneur lorsqu’ils ne sont pas en mode LiveWindow