Dashboard Tutorial fro Java Pls :)

It may not be vital, but i would like to know how to modify the dashboard display inorder to display some variables. Im not sure how, but all i want to track to test is a boolean via a push button, not display (since we ran outta easy-access lines :P) Anyone able to supply us with a tutorial or documentation?

If you are referring to the default dashboard as opposed to ZomB or one of the other community dashboards, then you are in for a rough time. There is no documentation provided (as far as I am aware) and the example code is brutal.
From FIRST’s DashboardExample.java:

void updateDashboard() {
        Dashboard lowDashData = DriverStation.getInstance().getDashboardPackerLow();
        lowDashData.addCluster();
        {
            lowDashData.addCluster();
            {     //analog modules
                lowDashData.addCluster();
                {
                    for (int i = 1; i <= 8; i++) {
                        lowDashData.addFloat((float) AnalogModule.getInstance(1).getAverageVoltage(i));
                    }
                }
                lowDashData.finalizeCluster();
                lowDashData.addCluster();
                {
                    for (int i = 1; i <= 8; i++) {
                        lowDashData.addFloat((float) AnalogModule.getInstance(2).getAverageVoltage(i));
                    }
                }
                lowDashData.finalizeCluster();
            }
            lowDashData.finalizeCluster();

            lowDashData.addCluster();
            { //digital modules
                lowDashData.addCluster();
                {
                    lowDashData.addCluster();
                    {
                        int module = 4;
                        lowDashData.addByte(DigitalModule.getInstance(module).getRelayForward());
                        lowDashData.addByte(DigitalModule.getInstance(module).getRelayForward());
                        lowDashData.addShort(DigitalModule.getInstance(module).getAllDIO());
                        lowDashData.addShort(DigitalModule.getInstance(module).getDIODirection());
                        lowDashData.addCluster();
                        {
                            for (int i = 1; i <= 10; i++) {
                                lowDashData.addByte((byte) DigitalModule.getInstance(module).getPWM(i));
                            }
                        }
                        lowDashData.finalizeCluster();
                    }
                    lowDashData.finalizeCluster();
                }
                lowDashData.finalizeCluster();

                lowDashData.addCluster();
                {
                    lowDashData.addCluster();
                    {
                        int module = 6;
                        lowDashData.addByte(DigitalModule.getInstance(module).getRelayForward());
                        lowDashData.addByte(DigitalModule.getInstance(module).getRelayReverse());
                        lowDashData.addShort(DigitalModule.getInstance(module).getAllDIO());
                        lowDashData.addShort(DigitalModule.getInstance(module).getDIODirection());
                        lowDashData.addCluster();
                        {
                            for (int i = 1; i <= 10; i++) {
                                lowDashData.addByte((byte) DigitalModule.getInstance(module).getPWM(i));
                            }
                        }
                        lowDashData.finalizeCluster();
                    }
                    lowDashData.finalizeCluster();
                }
                lowDashData.finalizeCluster();

            }
            lowDashData.finalizeCluster();

            lowDashData.addByte(Solenoid.getAll());
        }
        lowDashData.finalizeCluster();
        lowDashData.commit();

    }

Baffling and undocumented. I would look to the community dashboards.

Ty for your help, maybe i will, but after bagging.

I wrote up a custom object that lets you track variables and output more easily on the lcd in the bottom right. If you’d like, I can post it.

That would be cool, especially since i want to track the state of some switches we have…

package edu.wpi.first.wpilibj.defaultCode;

import edu.wpi.first.wpilibj.DriverStationLCD;
import edu.wpi.first.wpilibj.DriverStationLCD.Line;
/**
 * Let me know if you use this code! I'd like to hear
 * whether it worked or not, and that there are teams that use it.
 * @author ArchVince
 * team 1290
 */
public class SimpleLCD {
    String print];
    String over, overflow;
    Object moniAr];
    Line lines];
    int watching;

    public SimpleLCD(){
        watching = 0;
        moniAr = new Object[6];
        lines = new Line[6];
        lines[0] = Line.kMain6;
        lines[1] = Line.kUser2;
        lines[2] = Line.kUser3;
        lines[3] = Line.kUser4;
        lines[4] = Line.kUser5;
        lines[5] = Line.kUser6;
        over = " ";
        for(int y = 1; y < DriverStationLCD.kLineLength; y++) over += " ";
        print = new String[6];
        for(int x = 0; x < print.length; x++) print[x] = " ";
        for(int x = 0; x < print.length; x++) for(int y = 1; y < DriverStationLCD.kLineLength; y++) print[x] += " ";
    }
    public void upd(){
        int curr = 0;
        for(int x = 0; x < 5; x++){
            if(moniAr[x]!=null){
                DriverStationLCD.getInstance().println(lines[curr], 1, over);
                DriverStationLCD.getInstance().println(lines[curr], 1, moniAr[x].toString());
                DriverStationLCD.getInstance().updateLCD();
                curr++;
            }
        }
    }
    public boolean stopMonitor(int test){
        boolean found = true;
        if(moniAr[test] == null) found = false;
        moniAr[test] = null;
        if(found)watching--;
        return found;
    }
    public boolean monitor(Object watch, int test){
        if(watching == lines.length && moniAr[test] == null) return false;
        else{
            if(moniAr[test] == null) watching++;
            moniAr[test] = watch;
            return true;
        }
    }
    public void output(String out){
        overflow = "";
        if(out.length()>DriverStationLCD.kLineLength)out.substring(DriverStationLCD.kLineLength);
        for(int x = watching; x < 5; x++) print[x] = print[x+1];
        print[5] = out;
        cls();
        for(int x = watching; x < 5; x++) DriverStationLCD.getInstance().println(lines[x], 1, print[x]);
        DriverStationLCD.getInstance().updateLCD();
        if(!overflow.equals("")) output(overflow);
    }
    public void cls(){
        for(int x = watching; x < 5; x++) DriverStationLCD.getInstance().println(lines[x], 1, over);
        DriverStationLCD.getInstance().updateLCD();
    }
}

That’s SimpleLCD.java.

I don’t have any documentation for it, but I’ll summarize how to use it. Make a simpleLcd object with:

SimpleLCD lcd = new SimpleLCD();

lcd.output is a method that takes in a string and prints it to the screen. It should automagically wrap it handle which line ot put it on; if you have any problems PM me.

To monitor a variable:
lcd.monitor needs two arguments. First is the variable itself. It needs to be in object format, but it should be able to automatically do get the object from a string or the like. You may need to wrap primitive data types, such as ints. The second is the number. If it’s the first one, just pass 1. Second, pass 2, etc.TO do so:


String woo = "yay";
//Put these next lines inside a function that is called repeatedly. In our case, we have inside teleopPeriodic()
lcd.monitor(woo, 1);
lcd.upd();

lcd.upd() MUST be called at the end of the periodic loop for it to work. I’m not to great at explaining how to use it, so please ask questions. Oh, and you can call lcd.cls() to clear the lcd screen.

We started with the approach of using the LCD on the Driver Station by doing something similar, because we thought that was the best we were going to be able to accomplish.

But, if you look at my post to bascially the same question on “Info to Dashboard” started by sand500 (sorry, I don’t know how to link here), then you’ll see the information you need to get you into the ‘real’ Dashboard with LabView.

I know lots about Java programming, but our team had zero LabView experience, and we managed to make this work - so I’m sure you can too.

Good luck!

Documentation of the example code can be found here. Also, there is a document available by Joe Ross that explains how to modify it in Labview. I couldn’t get things to work exactly as described in the doc, but close enough I could figure out how the code works and where to add things, both in the Labview code and in the java code.

I started using SmartDashboard last night though, and it’s much easier. Only problem there is getting the driver station to launch it automatically. Someone posted a “fix” that would do this, but it doesn’t seem to work for me.

@ 2 above : I do have LabVIEW experience, as last year for breakaway i did the programming all in LabVIEW, but i never messed with the dashboard. @above, thx for documentation.

A further note on this, and a question on LabView programming …

(1) If you use any of the default Dashboard (namely the display of the digitial stuff from the sidecars) - it turns out that the WPI code returns the DIO data in FPGA order, not laptop display order. So you end up displaying 2 bits (14 & 15) that mean nothing, don’t display 2 bits (0 & 1) and everything else is in reverse order. Since I’m not a LabView programmer, I put the code in Java on the robot to reverse the bits in this set of calls (after I get the data and before I add it):

lowDashData.addShort(DigitalModule.getInstance(module).getAllDIO());
lowDashData.addShort(DigitalModule.getInstance(module).getDIODirection());

(2) Now my question … we are using two digitial sidecars this year, and although the code appears to get the data (from module 4 and module 6), the default(?) display only displays module 4. We were able to get all our custom data wired into the display, but haven’t been able to figure out yet how to create a copy of the module 4 display and wire it to the second set of data in the cluster / array. Our team has zero experience with LabView (other than what we’ve managed to do in the last six weeks). I can see the building blocks in the wiring diagram, and more or less understand what it’s doing (to convert the cluster to the array, and then extract the data with an index selector). But if someone could point me to an example or give a hint on how to wire / extract the second module, and get it displayed with the same UI stuff in the dashaboard, I’d appreciate it.

Thanks!

There are two parts to this. One, update the Java robot code to read and update the values for the second digital slot. I don’t have access to the Java code, so I can’t help much with this part.

The second part is to update the code for the custom dashboard. If you haven’t done it yet, create a dashboard project from the Getting Started window. Open the Dashboard Main VI. Duplicate the group of displays for slot 4 and make one for six. You can do this by ctl-clicking and dragging a copy to the right, or you can copy/paste. You may also want to grow the window and move around the solenoids, communications, and other stuff. All of the controls are grouped to make them be a bit easier to rearrange.

If you double click on the test that says slot four, it should be selected and you can rename it. If you double click on the PWMs, LV will take you to the diagram and hilite the terminal that needs to have data wired. Notice that the original PWM is wired to the outputs of a VI called Parse Digital Module. There is a second VI just beneath, and you only need to drag the four terminals into the same structure and wire them to the Parse outputs. Hopefully that is enough info.

If you decide to duplicate only some of the digital displays, I’d start as above, then ungroup and delete what you aren’t using. Click on the new Slot 6 displays, click on the Reorder toolbar button – second from the right, looks like circular arrows, and choose ungroup. You can how click around and delete items you don’t want to wire up anyway. Note that the clusters, arrays, and other display containers are painted transparent, which means they are a bit hard to see where to click. You may find it easier to start from the diagram terminal of the control you want to delete, double click, and LV will flip to the panel and select the item. If you simply want to delete it, you can most likely delete it from the diagram as well – depends on ini settings.
There is no need to regroup the controls if you don’t want. Grouping has no impact on the form of the data. If you do something that seems odd, Undo is your friend.

Feel free to ask other questions.

Greg McKaskle

Greg -

This worked perfectly (just as you described it). Thank you so much for your help!

Stu