Toggle Switch Button inside ShuffleBoard

Is there a way to add a ToogleSwitch Button widget to ShuffleBoard and link it to Command?

I’m not sure about shuffleboard, but on smartdashboard it looks a little like this:

frc2::Trigger dashbutton([this] { return frc::SmartDashboard::GetBoolean("my value key", false); });

dashbutton.ToggleOnTrue(my_command);

And there is no way to do it in the ShuffleBoard?

That’s not what was said.

Both SmartDashboard and Shuffleboard communicate over NetworkTables, so if the individual API doesn’t provide what you need, you can read NetworkTables directly. That said, Shuffleboard does have both Toggle Button and Toggle Switch widgets that you can use. With ShuffleBoard, you would add the entry (using the example shown in the javadocs here), set the widget type you want (i.e. Toggle Button). You can then call getEntry() to return a NetworkTables entry object, which will allow you to fetch the value in your code.

Once you have a way of fetching the value, you can use it in a Trigger like what @Cynosure suggested.

I used java since that’s what I’m more familiar with and you didn’t specify what you’re using. If you need C++ or Python, similar docs exist for those, but that’s an exercise for the reader.

1 Like

Something resembling this in Java. Use the SmartDashboard tab in ShuffleBoard and change the boolean to another widget as you like.

boolean mySwitch;
Trigger startMyCommand;

  @Override
  public void robotInit()
  {
    Timer.delay(2.);
    mySwitch = false;
    SmartDashboard.putBoolean("MySwitch", mySwitch);

    MyCommand myCommand = new MyCommand();
    startMyCommand = new Trigger( ()-> mySwitch )
      .whileTrue(myCommand);
  }

  @Override
  public void robotPeriodic()
  {
      mySwitch = SmartDashboard.getBoolean("MySwitch", false);

      CommandScheduler.getInstance().run();
  }

If you just put a command on Shuffleboard or SmartDashboard it already is a button that can be pressed to schedule the command.

Why would you need a toggle switch trigger to schedule a command when clicking the button schedules it already?

How do you put a Command on the DashBoard? Are you referring to putData/getData or the radio buttons SendableChooser? We tend not to want to instantiate all the possibilities too early as we change our mind at initialization time. But I’d like to know a good way to assign the command to a widget.

Yes, if you putData and have the sendable be a Command, it will be a button you press to schedule it, and then, while it is running the button will display as pressed, and when you click it again, it will cancel it.

As far as initialization time changes, you could always just put those as Network Tables entries as well, and grab them in the initialize method of the command. In fact, that’s generally the way I teach the students to iterate their software. Put the tunable values on the dashboard and run commands that use them until you get the results you want. Then lock those in to code.

Allows for much faster iteration since you don’t have to re-deploy code for every tweak test.

1 Like

This is a pretty clean way to do it. This is in C++, but i am guessing it will work in Java as well. You can change the Widget Type kToggleSwitch instead of you don’t want it to be a push button.

Needs a variable in your object somewhere that acts as its boolean .

 bool              m_resetGyroButton;

This code adds the a button to Shuffleboard and then links its created Network Table Location to a Network Button.

  /* Add a button to reset the gyro using a triggered network button    */
  /* command.  Note this clears the boolean after running the function  */
  /* to zero heading.                                                   */
  frc::Shuffleboard::GetTab("Subsystems").GetLayout("Drive").AddBoolean("Reset Gyro", [this]{ return(m_resetGyroButton); }).WithWidget(frc::BuiltInWidgets::kToggleButton).WithProperties({{"Label position", nt::Value::MakeString("HIDDEN")}}).WithPosition(3, 1);
  frc2::NetworkButton(nt::NetworkTableInstance::GetDefault().GetBooleanTopic("/Shuffleboard/Subsystems/Drive/Reset Gyro")).OnTrue(frc2::cmd::RunOnce([this] { m_drive.ZeroHeading(); m_resetGyroButton = false; }, {&m_drive}));  

** NOTE ** The location of the Boolean Topic is based on the location you give for your button (Tab/Layout/Item Name). You will need to change this to point to the correct network table entry based on how you have located and named your button.

If this doesn’t work for you, you should checkout the other NetworkButton APIs there might be something else in there that will do what you want instead.

1 Like

Thanks to @NewtonCrosby, this morning I have already added a SmartDashboard Start/Cancel command button and ripped out the several statements I posted above to a project I’m working on.

In Java, and if you want to dumb it down all the way and use the Smartdashboard tab in Shuffle board or the real SmartDashboard (which I do) all you need is:
SmartDashboard.putData("my command label", myCommand));

WPILib is like the “drinking from a firehose.” I had missed this technique.

I don’t claim that we do things correctly or optimally, but I think that more teams that are in the beginning/middle class of software would do themselves a lot of good and save themselves a lot of time in making their testing more efficient using the Dashboards available.

To maybe inspire some other ideas for you, you can see how we built out test tabs in our Robot instantiation, and then used it to tune PIDs in our drivetrain.

Then once you have things tuned, certainly for your competition code you lock in the constants you derived in testing, and I believe that for competitions we would comment out the methods that built all the test specific dashboard pieces in robotInit so we wouldn’t have so many network tables entries refreshing.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.