We have been trying to use Network tables to grab variables from RoboRealm and use them in our robot program. We keep encountering an error whenever we even remotely use the NetworkTables class in our code.
ERROR Unhandled exception instantiating robot org.usfirst.frc.team4959.robot.Robot java.lang.IllegalStateException: Network tables has already been initialized at [edu.wpi.first.wpilibj.networktables.NetworkTable.checkInit(NetworkTable.java:31), edu.wpi.first.wpilibj.networktables.NetworkTable.setPersistentFilename(NetworkTable.java:123), edu.wpi.first.wpilibj.RobotBase.<init>(RobotBase.java:63), edu.wpi.first.wpilibj.IterativeRobot.<init>(IterativeRobot.java:57), org.usfirst.frc.team4959.robot.Robot.<init>(Robot.java:26), sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method), sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62), sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45), java.lang.reflect.Constructor.newInstance(Constructor.java:408), java.lang.Class.newInstance(Class.java:433), edu.wpi.first.wpilibj.RobotBase.main(RobotBase.java:204)]
We believe due to the error that somehow the Network Table we are trying to create has already been created,but have no idea on how to use it in our code.
It is possible we are misusing RoboRealm as this is our first year using the software. We followed the basic tutorial and used the basic vision tracking file provided by RoboRealm. From there we have added our axis camera and successfully gotten feed into RoboRealm. After all the functions provided by the file made by RoboRealm we have created a network table to send variables though and selected the variables we want to send into the network.
If you need any more information on our code just ask. You can find our git hub here
We have not been able to find any other fix from our research on the internet (like 6th page of Google deep) so if anyone has an idea as to what to do or what we are doing wrong please help. Thank you!
Oh sorry, the current git code is not exactly up to date. Anytime that we try to create or access a Network Tables object, it gives us the error above. No matter where we make it or what we do with it, it still gives us that error. Even without the initialize()
This is some basic code we have been trying. We are still getting the same error. Any time we try to access the NetworkTables class we receive the error.
NetworkTable server;
public Vision() {
server = NetworkTable.getTable("SmartDashboard");
}
public void printImageCount() {
try {
double imageCount = server.getNumber("IMAGE_COUNT", 0.0);
System.out.println(imageCount);
}
catch(TableKeyNotDefinedException exp) {
}
}
Here is an stand alone example program I have been using (run as a Java application, not as a Robot program) that connects to our network tables, monitors and then clears the “SmartDashboard” entries.
If you are running your program outside of a robot project, then maybe the way we do our set up would apply to you as well.
package com.techhounds.dashboard;
import edu.wpi.first.wpilibj.networktables.NetworkTable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.tables.ITableListener;
/**
* A utility to delete (clear) the SmartDashboard keys from the NetworkTable.
*
* @author pkb
*/
public class ClearDashboard implements ITableListener {
/**
* Entry point into the application.
*
* @param args You can specify the IP address of the NetworkTable server to connect to on the command line.
*
* @throws InterruptedException If there is a problem accessing the SmartDashboard table.
*/
public static void main(String args]) throws InterruptedException {
ClearDashboard cd = new ClearDashboard();
String defaultIp = "10.8.68.2";
//String defaultIp = "127.0.0.1";
String ipAddr = (args.length > 0) ? args[0] : defaultIp;
NetworkTable.setIPAddress(ipAddr);
NetworkTable.setClientMode();
NetworkTable.initialize();
NetworkTable table = NetworkTable.getTable("SmartDashboard");
table.addTableListener(cd);
table.addSubTableListener(cd);
table.putBoolean("Cleared", false);
// Give a bit of time to allow network fetch of keys to show up
Thread.sleep(1000);
deleteTableKeys(table, "", true);
// Give a bit of time for network operations to flush out
Thread.sleep(500);
// Put value back (for testing)
// table.putBoolean("Cleared", true);
}
/**
* Helper method to recursively delete NetworkTable key/value pairs.
*
* @param table The NetworkTable to clear key/value pairs from.
* @param indent The leading indent (like: " ") for printing out info.
* @param deleteTable Should we delete the table after clearing its children.
*/
private static void deleteTableKeys(ITable table, String indent, boolean deleteTable) {
System.out.println(indent + table);
indent += " ";
// Delete key/value pairs from table
for (String key : table.getKeys()) {
Object value = table.getValue(key, null);
System.out.println(indent + key + " : " + value);
table.delete(key);
}
// Process any sub-tables
for (String key : table.getSubTables()) {
ITable subTable = table.getSubTable(key);
System.out.println(indent + key + " {");
// Is it save to delete table entries (and if so should we delete children first?)
deleteTableKeys(subTable, indent, true);
System.out.println(indent + "}");
if (deleteTable) {
table.delete(key);
}
}
}
/**
* Let's us know as values come in.
*/
@Override
public void valueChanged(ITable table, String key, Object value, boolean flag) {
System.out.println("table: " + table + " key:" + key + " value: " + value + " flag: " + flag);
}
}
I’m also trying to make a NetworkTables desktop client for a SmartDashboard vision widget, and I’m doing the exact same initialization steps that you are, in the same order, but I’m still getting a “Network tables has already been initialized” error. Any idea on what this might be?
EDIT: So it turns out that the source of the error is NetworkTable.setIPAddress(), whether it’s called before or after NetworkTable.getTable().
The demo program I included was for a stand alone Java application (it runs outside of the Robot code and outside of the SmartDashboard).
It sounds like you are creating a SmartDashboard extension (plugin) module that is loaded by the SmartDashboard and run inside the SmartDashboard. If this is the case, then my guess is that the SmartDashboard has already set up and constructed the single instance of the NetworkTable connection object.
If you want to update values in a network table, my assumption is that you would skip all of the initialization steps and just grab the table you want to work with when you want to put a value out (similar to what you would do in Robot code). Something like: