Go to Post There's the problem!! The #1 reason to blame the programmers: They always forget to grease their code. :rolleyes: - Jack Jones [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 20-02-2011, 11:52
sand500 sand500 is offline
Registered User
FRC #3540 (Wildcat Robotics)
 
Join Date: Jan 2011
Rookie Year: 2011
Location: United States
Posts: 81
sand500 is an unknown quantity at this point
Info to Dashboard

i looked around and no one seems to know what code to use to send data to a custom dashboard. Some one said to use the Driver Station class but that doesnt seem to have any method that would be useful. Any one have any ideas on what code is used to send data so a custom dashboard. also, we made the dashboard in labview.
Reply With Quote
  #2   Spotlight this post!  
Unread 20-02-2011, 20:59
Patrickwhite's Avatar
Patrickwhite Patrickwhite is offline
May the North be with you
FRC #0610 (The Coyotes)
Team Role: Programmer
 
Join Date: Dec 2008
Rookie Year: 2008
Location: Toronto
Posts: 88
Patrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of light
Re: Info to Dashboard

Any information sent to the dashboard (regrettably) has to go through the incredibly obtuse system of sending 'clusters' of data, example below. Using a custom dashboard doesn't change that.

WPI's DashboardExample.java:
Code:
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();

    }
I wouldn't even know where to start editing that to send custom data.
__________________
while(!going.isTough());
tough.exit();

What will we do tonight, Warfa?
The same thing we do every night, Patrick. Sit and wait for Electrical.
Reply With Quote
  #3   Spotlight this post!  
Unread 21-02-2011, 07:13
java4first java4first is offline
(Java) Programming Mentor
AKA: Stu
FRC #0501 (Power Knights)
Team Role: Mentor
 
Join Date: Nov 2010
Rookie Year: 2011
Location: Goffstown, NH
Posts: 56
java4first is an unknown quantity at this point
Re: Info to Dashboard

Actually, the sending of the extra data is the least of your problems.

Attached is a snippet of code from our DashboardManager ... you just add it after the solenoid stuff (which is the old version of the example code from WPI and won't work with the new library). There are a bunch of addXxxxx methods depending on the data type you want to send.

The hard part is getting the LabView coded to update the Dashboard itself by reading and processing the extra data you send at the end of the message. We found a document on line that helped get us over that hurdle (although it was somewhat dated and missing some stuff). If you Google on "LabView dashboard Joe Ross Team 330 1/11/2010" you should find it. It's on some publishing site where you have to upload a document to be able to download a document, or else pay for a membership. If you have anyone with any LabView experience, I'm sure it will be less painful for you.

Good luck!

}
lowDashData.finalizeCluster( );

lowDashData.addByte( Solenoid.getAllFromDefaultModule( ) );
}
// **** beginning of inserted code

/*
* Add our custom data to end of message
*/
{
lowDashData.addDouble( armAngle );

lowDashData.addBoolean( leftSensor );
lowDashData.addBoolean( centerSensor );
lowDashData.addBoolean( rightSensor );

lowDashData.addBoolean( redLED );
lowDashData.addBoolean( whiteLED );
lowDashData.addBoolean( blueLED );
}

// *** end of inserted code
lowDashData.finalizeCluster( );
lowDashData.commit( );
}
Reply With Quote
  #4   Spotlight this post!  
Unread 21-02-2011, 09:45
wdell wdell is offline
Registered User
AKA: William Dell
FRC #3999 (Shadetree Mechanics)
Team Role: Mentor
 
Join Date: Jan 2011
Rookie Year: 2010
Location: Killeen, Texas
Posts: 55
wdell has a spectacular aura aboutwdell has a spectacular aura about
Re: Info to Dashboard

I decoded the example dashboard code a while back, you can find the explanation here.

Attached is the Joe Ross document, so you don't have to pull it off that site. It's what I used to figure out the example code. Takes some careful reading, but between that and my commented code you should be able to figure out where to add stuff.
Attached Files
File Type: pdf 27095630-LabVIEW-Dashboard.pdf (687.3 KB, 23 views)
Reply With Quote
  #5   Spotlight this post!  
Unread 21-02-2011, 19:44
Patrickwhite's Avatar
Patrickwhite Patrickwhite is offline
May the North be with you
FRC #0610 (The Coyotes)
Team Role: Programmer
 
Join Date: Dec 2008
Rookie Year: 2008
Location: Toronto
Posts: 88
Patrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of lightPatrickwhite is a glorious beacon of light
Re: Info to Dashboard

I've been meaning to write [a class/some classes] that simplif[y/ies] use of the default dashboard, is anyone aware of something similar that already exists? If it does, I'm not going to reinvent the wheel, but it needs better methods than some arbitrarily named methods. The community dashboards are great, but I'd like code that works right out of the box.
__________________
while(!going.isTough());
tough.exit();

What will we do tonight, Warfa?
The same thing we do every night, Patrick. Sit and wait for Electrical.
Reply With Quote
  #6   Spotlight this post!  
Unread 22-02-2011, 15:51
wdell wdell is offline
Registered User
AKA: William Dell
FRC #3999 (Shadetree Mechanics)
Team Role: Mentor
 
Join Date: Jan 2011
Rookie Year: 2010
Location: Killeen, Texas
Posts: 55
wdell has a spectacular aura aboutwdell has a spectacular aura about
Re: Info to Dashboard

Quote:
Originally Posted by Patrickwhite View Post
I've been meaning to write [a class/some classes] that simplif[y/ies] use of the default dashboard, is anyone aware of something similar that already exists? If it does, I'm not going to reinvent the wheel, but it needs better methods than some arbitrarily named methods. The community dashboards are great, but I'd like code that works right out of the box.
Here's what I use to communicate with the driver station and default dashboard:
Code:
package edu.wpi.first.wpilibj.templates;

/**
 * @author   William Dell
 * @author   Team 647
 * @version  v7, January 26, 2011
 * @version  FRC Java version 2011.4
 */
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.DriverStationLCD;
import edu.wpi.first.wpilibj.Dashboard;
import edu.wpi.first.wpilibj.AnalogModule;
import edu.wpi.first.wpilibj.DigitalModule;
import edu.wpi.first.wpilibj.Solenoid;

/**
 * The routines for dealing with the driver station are ridiculously complicated
 * and cryptic.  Hopefully this class will simplify the process by replacing them
 * with shorter, more obvious methods.
 */
public class DStation implements Runnable {

    // going to treat the LCD as a stack, in reverse here because
    // new lines appear on the bottom and scroll upwards (mostly)
    DriverStationLCD.Line[] lcdLines = {
        DriverStationLCD.Line.kUser6, // bottom line
        DriverStationLCD.Line.kUser5,
        DriverStationLCD.Line.kUser4,
        DriverStationLCD.Line.kUser3,
        DriverStationLCD.Line.kUser2,
        DriverStationLCD.Line.kMain6 // top line
    };
    String[] lcdHistory = new String[6];  // array to scroll lcd display
    String clearLine = "                     "; // 21 spaces to clear a line

    Main robbie;
    // empty constructor
    public DStation(Main mainBot) {
        robbie = mainBot;
    } // end constructor

    /**
     * When run, the class starts a continuous loop to update the dashboard
     * constantly.  This is probably a bad way to do it.
     */
    public void run() {

        // caution, infinite loop, this could be bad....
        while (true) {
            updateDashboard();
        } // end while
        // but it actually works!

    } // end method run()

    /**
     * Messages to the LCD must be 21 characters long or you get artifacts
     * from previous lines.  This should pad the desired message out to 
     * the proper length.
     * 
     * @param msg  the message to be padded out
     * @return  line  the message line padded out to 21 characters
     */
    private String padMsg(String msg) {
        String line = msg;
        if (line.length() < 21) {  // if the message is already 21 or more do nothing
            // otherwise tack on however many spaces we are short
            for (int i = msg.length() + 1; i <= 21; i++) {
                line += " ";
            } // end for
        } // end if
        line = line.substring(0, 21); // make sure we are only 21 long
        return line; // and return the new, padded out line

    } // end method padMsg()

    /**
     * Does just what it says, clears the driver station LCD.
     */
    public void clearLCD() {
        for (int i = 0; i < 6; i++) {
            lcdHistory[i] = clearLine; // clear the lcd "memory"
            // and then use the cleared memory to clear the actual display
            DriverStationLCD.getInstance().println(lcdLines[i], 1, lcdHistory[i]);
        } // end for
        DriverStationLCD.getInstance().updateLCD();  // display the screen

    } // end method clearLCD()

    /**
     * Simplified messages to the LCD, with scrolling; new messages appear at
     * the bottom of the screen and scroll up.
     * 
     * @param msg  the message to be sent to the screen
     */
    public void sendToLCD(String msg) {

        // scroll down the history;  iterate backwards!
        for (int i = 5; i > 0; i--) {
            lcdHistory[i] = clearLine;
            lcdHistory[i] = lcdHistory[i - 1];
        } // end for
        lcdHistory[0] = clearLine; // clear the bottom line of the screen
        lcdHistory[0] = padMsg(msg); // insert new line at the bottom, padded out to 21 chars

        // set up updated screen by rewriting all lines
        for (int i = 0; i < 6; i++) {
            DriverStationLCD.getInstance().println(lcdLines[i], 1, lcdHistory[i]);
        } // end for
        DriverStationLCD.getInstance().updateLCD(); // display the screen

    } // end method sendToLCD()

    /** 
     * This makes it easier to send message to a specific line.  Takes the 
     * desired line number (top to bottom, 1-6) and the message to print as
     * arguments.
     * 
     * @param line  which line of the LCD the message should be displayed on
     * @param msg   the message to be displayed
     */
    public void toLCDLine(int line, String msg) {

        int index = 6 - line; // array is set up bottom to top, this reverses it
        DriverStationLCD.getInstance().println(lcdLines[index], 1, padMsg(msg));
        DriverStationLCD.getInstance().updateLCD(); // keep forgetting this, d'oh!

    } // end method toLCDLine()

    
    /**
     * Taken from DashboardExampleProject.  I'll try to explain how this is 
     * organized.
     * 
     * The LabView dashboard is organized with all the various displays in
     * "clusters".  These clusters are embedded in other clusters, which are
     * embedded in others, and so on.  For example, PWM display 1 is embedded
     * in the cluster for Digital Module 0, which is embedded in Digital
     * Cluster 1, which is in the cluster containing all the digital modules,
     * which is in the cluster containing everything.  Whew.  Basically it's 
     * a tree structure.
     * 
     * To send information to the dashboard, you have to "pack" this tree,
     * filling in all the various clusters with the correct data, and then 
     * send the whole tree at one time to the dashboard.  You create the
     * tree by using the addCluster() method, nesting each lower level of the
     * tree in the higher ones.  When a cluster is loaded you finalize it, 
     * which basically packs up that particular module for shipment to the 
     * dashboard.  After all the clusters are finalized you use the commit()
     * method to send it to the dashboard.
     * 
     * I've extracted the tree structure from the LabView dashboard code to
     * interpret what's below.  I'll try to provide enough comments for you
     * to understand which module is where, and which instrument display it
     * connects to.
     * 
     * To keep the dashboard up to date you have to call this method repeatedly,
     * either in an infinite loop or in teleopContinuous() if you use 
     * IterativeRobot.  I use an infinite loop running in a separate thread.
     */
    void updateDashboard() {
        
        // first, get an instance of the dashboard "packer" file.  This is 
        // essentially a map of how the dashboard has the clusters configured.
        Dashboard lowDashData = DriverStation.getInstance().getDashboardPackerLow();

        // We now recreate the tree using the addCluster method, nesting
        // the individual display panels.
        
        // First, the overall container that holds everything else
        lowDashData.addCluster();  // overall container
        {
            // There are 3 clusters in the next level, the analog modules,
            // the digital modules, and the solenoids.
            
            // Add the cluster containing the analog modules.
            lowDashData.addCluster();
            {
                // The analog module cluster contains two analog modules, one
                // for each of the first two slots on the cRio.
                
                // Add the cluster for Analog Module 0 (Slot One on the cRio)
                lowDashData.addCluster();
                {
                    // Here we just iterate through the analog ports, adding
                    // float values containing the average voltage for the given
                    // port.
                    for (int i = 1; i <= 8; i++) {
                        lowDashData.addFloat((float) AnalogModule.getInstance(1).getAverageVoltage(i));
                    }
                }
                // Finished with Analog Module 0, finalize the cluster
                lowDashData.finalizeCluster(); // finalize analog module 0

                /// Add the cluster for Analog Module 1 (Slot Two on the cRio)
                lowDashData.addCluster();
                {
                    // And again, iterate through the voltages for each port
                    // on the module
                    for (int i = 1; i <= 8; i++) {
                        lowDashData.addFloat((float) AnalogModule.getInstance(2).getAverageVoltage(i));
                    }
                }
                // Finished with Analog Module 1, finalize the cluster.
                lowDashData.finalizeCluster(); // finalize analog module 1
            }
            // Done loading the data for the analog modules, so we finalize
            // the cluster that holds both of them.
            lowDashData.finalizeCluster(); // finalize analog cluster

            // Add the cluster containing the digital sub clusters.
            lowDashData.addCluster();
            {
                // The digital cluster contains two sub clusters, one for
                // slot 4 and one for slot 6 on the cRio.  Each of those
                // clusters contain modules for relays and for the PWM
                // slots.
                
                // Add the cluster for Digital SubCluster 1 (slot 4 on the cRio)
                lowDashData.addCluster();
                {
                    // The digital module itself contains two sub modules.
                    // The numbering system is screwey, but it's taken straight
                    // from the LabView code...
                    
                    // Add the cluster Digital Module 0 in SubCluster 1
                    lowDashData.addCluster();
                    {
                        int module = 4; // this specifies the cRio slot
                        
                        // And the next 4 lines handle relays
                        lowDashData.addByte(DigitalModule.getInstance(module).getRelayForward());
                        lowDashData.addByte(DigitalModule.getInstance(module).getRelayForward());
                        lowDashData.addShort(DigitalModule.getInstance(module).getAllDIO());
                        lowDashData.addShort(DigitalModule.getInstance(module).getDIODirection());

                        // Add the cluster for PWM module 1 - I know for a fact
                        // that these are the 10 PWM connections on the digital
                        // sidecar hooked to the module in cRio Slot 4 :)
                        lowDashData.addCluster();
                        {
                            // Iterate through the PWM values for each port
                            for (int i = 1; i <= 10; i++) {
                                lowDashData.addByte((byte) DigitalModule.getInstance(module).getPWM(i));
                            }
                        }
                        // Finished with PWM Module 1, finalize the cluster.
                        lowDashData.finalizeCluster(); // finalize PWM 1
                    }
                    // And finished with Digital Module 0
                    lowDashData.finalizeCluster(); // finalize digital module 0
                }
                // And with Digital SubCluster 1
                lowDashData.finalizeCluster(); // finalize subcluster 1

                // Add the cluster for Digital SubCluster 2 (slot 6 on the cRio)
                lowDashData.addCluster();
                {
                    // Add the cluster for Digital Module 1 in SubCluster 2
                    lowDashData.addCluster();
                    {
                        int module = 6; // cRio slot 6
                        
                        // And again, load the relay data
                        lowDashData.addByte(DigitalModule.getInstance(module).getRelayForward());
                        lowDashData.addByte(DigitalModule.getInstance(module).getRelayReverse());
                        lowDashData.addShort(DigitalModule.getInstance(module).getAllDIO());
                        lowDashData.addShort(DigitalModule.getInstance(module).getDIODirection());

                        // Add the cluster for PWM Module 2
                        lowDashData.addCluster();
                        {
                            // iterate through all 10 PWM ports
                            for (int i = 1; i <= 10; i++) {
                                lowDashData.addByte((byte) DigitalModule.getInstance(module).getPWM(i));
                            }
                        }
                        // Finished with PWM Module 2, finalize it.
                        lowDashData.finalizeCluster(); // finalize PWM 2
                    }
                    // Finished with Digital Module 2
                    lowDashData.finalizeCluster(); // finalize digital 2
                }
                // And done with Digital SubCluster 2
                lowDashData.finalizeCluster(); // finalize subcluster 2
            }
            // And that completes the entire Digital Cluster
            lowDashData.finalizeCluster(); // finalize digital cluster

            // The solenoids, for some reason, are not in a cluster of their
            // own, but are instead sitting in the overall container.  As such,
            // we don't need to addCluster() for them, we just need to add
            // the data.
            lowDashData.addByte(Solenoid.getAllFromDefaultModule());

            // If you are going to add instruments to the dashboard the
            // easiest place to put them is in the overall cluster, and then 
            // load the values for them here the same way the solenoid was
            // done.  Makes me think the solenoid was an afterthought.
            // Actually I think the whole dashboard was designed haphazardly
            // instead of in a planned manner, which is why this whole structure
            // sucks so bad.

        }
        
        // Once all the inputs are read and loaded, we close the overall container
        lowDashData.finalizeCluster(); // finalize entire tree structure.

        // We are now ready to send our packed up data tree to the dashboard
        // for display.
        lowDashData.commit(); // commit changes to update dashboard

    } // end method updateDashboard()

} // end class DStation
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 11:10.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi