Simulation User Interface

WPILib has extended robot simulation to introduce a graphical user interface (GUI) component. This allows teams to easily visualize their robot’s inputs and outputs.

Enabling the GUI

Currently, the only way to enable this feature is to modify your build.gradle file located at the root of your robot project. Simply add the below line into the dependencies {} section of your build.gradle.

simulation wpi.deps.sim.gui(wpi.platforms.desktop, false)

Important

C++ requires that you change the boolean false to true.

Your build.gradle should then look like the below

// Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries.
// Also defines JUnit 4.
dependencies {
    compile wpi.deps.wpilib()
    nativeZip wpi.deps.wpilibJni(wpi.platforms.roborio)
    nativeDesktopZip wpi.deps.wpilibJni(wpi.platforms.desktop)


    compile wpi.deps.vendor.java()
    nativeZip wpi.deps.vendor.jni(wpi.platforms.roborio)
    nativeDesktopZip wpi.deps.vendor.jni(wpi.platforms.desktop)

    simulation wpi.deps.sim.gui(wpi.platforms.desktop, false)

    testCompile 'junit:junit:4.12'
}

You may need to create a dependencies{} block in your build.gradle, as C++ projects do not normally have this. This can be positioned below the model{} block. It’s also important to note that C++ requires the boolean to be set to true instead of false. It should look like the following:

dependencies {
   simulation wpi.deps.sim.gui(wpi.platforms.desktop, true)
}

Running the GUI

Then you can simply launch the GUI via the Run Simulation command palette option.

Running simulation via VS Code

And the halsim_gui.dll option should popup in a new dialog. Select this and press Ok. This will now launch the Simulation GUI!

The simulation graphical user interface

Using the GUI

Learning the Layout

Simulation graphical user interface but with labels
  1. Robot State - This is the robot’s current state or “mode”. You can click on the labels to change mode as you would on the normal Driver Station.

  2. Relays - This includes any relay devices. This includes VEX Spike relays.

  3. Solenoids - This is a list of “connected” solenoids. When you create a solenoid object and push outputs, these are shown here.

  4. DIO - (Digital Input Output) This includes any devices that use the DIO connector on the roboRIO.

  5. Analog Inputs - This includes any devices that would normally use the ANALOG IN connector on the roboRIO, such as any Analog based gyros.

  6. PWM Outputs - This is a list of instantiated PWM devices. This will appear as many devices as you instantiate in robot code, as well as their outputs.

  7. Encoders - This will show any instantiated devices that extend or use the Encoder class.

  8. System Joysticks - This is a list of joysticks connected to your system currently.

  9. FMS - This is used for simulating many of the common FMS systems.

  10. Joysticks - This is joysticks that the robot code can directly pull from.

  11. Other Devices - This includes devices that do not fall into any of the other categories, such as the ADXRS450 gyro that is included in the Kit of Parts.

Adding a System Joystick to Joysticks

To add a joystick from the list of system joysticks, simply click and drag a shown joystick under the “System Joysticks” menu to the “Joysticks” menu”.

Dragging a joystick from System Joysticks to Joysticks

Modifying ADXRS450 Inputs

Using the ADXRS450 object is a fantastic way to test gyro based outputs. This will show up in the “Other Devices” menu. A drop down menu is then exposed that shows various options such as “Connected”, “Angle”, and “Rate”. All of these values are values that you can change, and that your robot code and use on-the-fly.

../../../../_images/sim-gui-using-gyro.png

Determing Simulation from Robot Code

In cases where vendor libraries do not compile when running the robot simulation, you can wrap their content with RobotBase.isReal() which returns a boolean.

TalonSRX motorLeft;
TalonSRX motorRight;

public Robot() {
 if (RobotBase.isReal()) {
   motorLeft = new TalonSRX(0);
   motorRight = new TalonSRX(1);
 }
}

Note

Reassigning value types in C++ requires move or copy assignment; vendors classes that both do not support the SIM and lack a move or copy assignment operator cannot be worked around with conditional allocation unless a pointer is used, instead of a value type.