|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
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.
|
|
#2
|
||||
|
||||
|
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();
}
|
|
#3
|
|||
|
|||
|
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( ); } |
|
#4
|
|||
|
|||
|
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. |
|
#5
|
||||
|
||||
|
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.
|
|
#6
|
|||
|
|||
|
Re: Info to Dashboard
Quote:
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
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|