From 057adc6df4b04bfbb2ef651c379a48e551a6d17d Mon Sep 17 00:00:00 2001 From: Sam Carlberg Date: Mon, 27 Jul 2015 17:10:16 -0400 Subject: Added support to the LiveWindow for CAN speed controllers Added PID velocity control and fixed PIDSubsystems Change-Id: I81bb4109cd1ff75b99b049a7ec2abd248ad3f9a1 --- .gitignore | 3 +- FakeRobot/build.xml | 147 +- ...beans-modules-java-j2seproject-copylibstask.jar | Bin 22335 -> 22977 bytes FakeRobot/lib/NetworkTables.jar | Bin 43275 -> 88068 bytes FakeRobot/lib/nblibraries.properties | 7 +- FakeRobot/nbproject/build-impl.xml | 2516 +++++++++++--------- FakeRobot/nbproject/genfiles.properties | 16 +- FakeRobot/nbproject/project.properties | 150 +- .../livewindowfakerobot/LiveWindowFakeRobot.java | 22 +- smartdashboard/build.gradle | 35 +- .../smartdashboard/gui/elements/PIDEditor.java | 231 +- .../gui/elements/bindings/AbstractTableWidget.java | 67 +- .../livewindow/elements/CANSpeedController.java | 242 ++ .../elements/LiveWindowWidgetRegistrar.java | 2 + .../livewindow/elements/PIDSubsystem.java | 45 + .../livewindow/elements/SpeedController.java | 5 + .../src/edu/wpi/first/smartdashboard/main.java | 34 +- .../types/named/CANSpeedControllerType.java | 27 + .../types/named/PIDSubsystemType.java | 3 +- 19 files changed, 2158 insertions(+), 1394 deletions(-) create mode 100644 smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/CANSpeedController.java create mode 100644 smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/PIDSubsystem.java create mode 100644 smartdashboard/src/edu/wpi/first/smartdashboard/types/named/CANSpeedControllerType.java diff --git a/.gitignore b/.gitignore index 25c67a2..02444b4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ smartdashboard/lib/NetworkTables* dist/ build/ target/ -.gradle/ \ No newline at end of file +.gradle/ +/FakeRobot/nbproject/ \ No newline at end of file diff --git a/FakeRobot/build.xml b/FakeRobot/build.xml index 427012b..6fc48d8 100644 --- a/FakeRobot/build.xml +++ b/FakeRobot/build.xml @@ -1,74 +1,73 @@ - - - - - - - - - - - Builds, tests, and runs the project FakeRobot. - - - + + + + + + + + + + + Builds, tests, and runs the project FakeRobot. + + + diff --git a/FakeRobot/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar b/FakeRobot/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar index 4cabe27..eaf6790 100644 Binary files a/FakeRobot/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar and b/FakeRobot/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar differ diff --git a/FakeRobot/lib/NetworkTables.jar b/FakeRobot/lib/NetworkTables.jar index 8ed6d45..f6f8cf6 100644 Binary files a/FakeRobot/lib/NetworkTables.jar and b/FakeRobot/lib/NetworkTables.jar differ diff --git a/FakeRobot/lib/nblibraries.properties b/FakeRobot/lib/nblibraries.properties index 81b4b5f..6d0afb5 100644 --- a/FakeRobot/lib/nblibraries.properties +++ b/FakeRobot/lib/nblibraries.properties @@ -1,3 +1,4 @@ -libs.CopyLibs.classpath=\ - ${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar -libs.CopyLibs.displayName=CopyLibs Task +libs.CopyLibs.classpath=\ + ${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar +libs.CopyLibs.displayName=CopyLibs Task +libs.CopyLibs.prop-version=2.0 diff --git a/FakeRobot/nbproject/build-impl.xml b/FakeRobot/nbproject/build-impl.xml index 0f3637b..f9b3d6c 100644 --- a/FakeRobot/nbproject/build-impl.xml +++ b/FakeRobot/nbproject/build-impl.xml @@ -1,1078 +1,1438 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set src.dir - Must set test.src.dir - Must set build.dir - Must set dist.dir - Must set build.classes.dir - Must set dist.javadoc.dir - Must set build.test.classes.dir - Must set build.test.results.dir - Must set build.classes.excludes - Must set dist.jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set JVM to use for profiling in profiler.info.jvm - Must set profiler agent JVM arguments in profiler.info.jvmargs.agent - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - - - - - - java -cp "${run.classpath.with.dist.jar}" ${main.class} - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - java -jar "${dist.jar.resolved}" - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - Must select one file in the IDE or set run.class - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set debug.class - - - - - Must select one file in the IDE or set debug.class - - - - - Must set fix.includes - - - - - - - - - - - - - - - - - Must select one file in the IDE or set profile.class - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - Some tests failed; see details above. - - - - - - - - - Must select some files in the IDE or set test.includes - - - - Some tests failed; see details above. - - - - - Must select one file in the IDE or set test.class - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FakeRobot/nbproject/genfiles.properties b/FakeRobot/nbproject/genfiles.properties index 3fda7d0..88a9e92 100644 --- a/FakeRobot/nbproject/genfiles.properties +++ b/FakeRobot/nbproject/genfiles.properties @@ -1,8 +1,8 @@ -build.xml.data.CRC32=42e58587 -build.xml.script.CRC32=65e52e08 -build.xml.stylesheet.CRC32=28e38971@1.50.3.46 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=42e58587 -nbproject/build-impl.xml.script.CRC32=3c08be4f -nbproject/build-impl.xml.stylesheet.CRC32=fcddb364@1.50.3.46 +build.xml.data.CRC32=42e58587 +build.xml.script.CRC32=bfcdca7e +build.xml.stylesheet.CRC32=8064a381@1.75.2.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=42e58587 +nbproject/build-impl.xml.script.CRC32=ca57dc8f +nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48 diff --git a/FakeRobot/nbproject/project.properties b/FakeRobot/nbproject/project.properties index fbbd528..3201a7e 100644 --- a/FakeRobot/nbproject/project.properties +++ b/FakeRobot/nbproject/project.properties @@ -1,75 +1,75 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=false -annotation.processing.processors.list= -annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.title=FakeRobot -application.vendor=Sam -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/FakeRobot.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.networktables-desktop-r158.jar=lib/networktables-desktop-r158.jar -includes=** -jar.compress=false -javac.classpath=\ - ${file.reference.networktables-desktop-r158.jar} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.processorpath=\ - ${javac.classpath} -javac.source=1.7 -javac.target=1.7 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -javac.test.processorpath=\ - ${javac.test.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -main.class=livewindowfakerobot.LiveWindowFakeRobot -manifest.file=manifest.mf -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project -# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value -# or test-sys-prop.name=value to set system properties for unit tests): -run.jvmargs= -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -src.dir=src -test.src.dir=test +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=FakeRobot +application.vendor=Sam +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/FakeRobot.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.NetworkTables.jar=lib/NetworkTables.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.NetworkTables.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=livewindowfakerobot.LiveWindowFakeRobot +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/FakeRobot/src/livewindowfakerobot/LiveWindowFakeRobot.java b/FakeRobot/src/livewindowfakerobot/LiveWindowFakeRobot.java index bfb544d..32666bf 100644 --- a/FakeRobot/src/livewindowfakerobot/LiveWindowFakeRobot.java +++ b/FakeRobot/src/livewindowfakerobot/LiveWindowFakeRobot.java @@ -20,13 +20,13 @@ public class LiveWindowFakeRobot { wPotentiometer = createTable(wrist, "Potentiometer", "Analog Input"), wVictor = createTable(wrist, "Victor", "Speed Controller"), - elevator = createTable(liveWindow, "Elevator", "LW Subsystem"), + elevator = createTable(liveWindow, "Elevator", "PIDSubsystem"), ePotentiometer = createTable(elevator, "Potentiometer", "Analog Input"), eVictor = createTable(elevator, "Victor", "Speed Controller"), testSys = createTable(liveWindow, "TestSystem", "LW Subsystem"), tComp = createTable(testSys, "Compressor", "Compressor"), - tGearTooth = createTable(testSys, "Gear Tooth Sensor", "Gear Tooth Sensor"), + tGearTooth = createTable(testSys, "Gear Tooth Sensor", "Gear Tooth"), tVictor = createTable(testSys, "Victor", "Speed Controller"), tPotentiometer = createTable(testSys, "Potentiometer", "Analog Input"), tRelay = createTable(testSys, "Spike", "Relay"), @@ -38,18 +38,32 @@ public class LiveWindowFakeRobot { tEncoder1 = createTable(testSys, "Encoder 1", "Encoder"), tUltra = createTable(testSys, "Ultrasonic", "Ultrasonic"), tCompass = createTable(testSys, "Compass", "Compass"), - tSwitch = createTable(testSys, "Limit Switch", "Digital Input"); + tSwitch = createTable(testSys, "Limit Switch", "Digital Input"), + + canSystem = createTable(liveWindow, "CAN Subsystem", "LW Subsystem"), + canJag = createTable(canSystem, "CAN Jaguar", "CANSpeedController"), + canTalon = createTable(canSystem, "CAN Talon", "CANSpeedController"); public static void main(String[] args) { System.out.println(); - STATUS.putBoolean("LW Enabled", false); + STATUS.putBoolean("LW Enabled", true); STATUS.putString("Robot", "Testing"); wPotentiometer.putNumber("Value", 2.6); ePotentiometer.putNumber("Value", -11.6872); tSwitch.putString("Value", "Off"); + elevator.putNumber("p", 0.5); + elevator.putNumber("i", 0.5); + elevator.putNumber("d", 0.5); + elevator.putNumber("f", 0.5); + elevator.putNumber("setpoint", 0.5); + elevator.putBoolean("enabled", false); + + canJag.putString("Type", "CANJaguar"); + canTalon.putString("Type", "CANTalon"); + (new Timer()).schedule( new TimerTask(){ diff --git a/smartdashboard/build.gradle b/smartdashboard/build.gradle index d373503..c85fee5 100644 --- a/smartdashboard/build.gradle +++ b/smartdashboard/build.gradle @@ -1,24 +1,27 @@ apply plugin: 'java' apply plugin: 'maven-publish' +apply plugin: 'application' + +mainClassName = "edu.wpi.first.smartdashboard.main" sourceSets { - main { - java.srcDir "src/" - } + main { + java.srcDir "src/" + } } dependencies { - compile 'edu.wpi.first.wpilib.networktables.java:NetworkTables:0.1.0-SNAPSHOT' - compile 'junit:junit:4.12' - compile 'jcommon:jcommon:0.9.5' - compile 'jfreechart:jfreechart:1.0.0' + compile 'edu.wpi.first.wpilib.networktables.java:NetworkTables:0.1.0-SNAPSHOT' + compile 'junit:junit:4.12' + compile 'jcommon:jcommon:0.9.5' + compile 'jfreechart:jfreechart:1.0.0' } repositories { - maven { - url "http://first.wpi.edu/FRC/roborio/maven/" - } - mavenCentral() + maven { + url "http://first.wpi.edu/FRC/roborio/maven/" + } + mavenCentral() } publishing { @@ -27,7 +30,7 @@ publishing { from components.java artifact (jar) { - classifier = 'jar' + classifier = 'jar' } groupId 'edu.wpi.first.wpilib' @@ -43,8 +46,8 @@ publishing { } jar { - manifest { - attributes 'Main-Class': 'edu.wpi.first.smartdashboard.main' - } - from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } + manifest { + attributes 'Main-Class': 'edu.wpi.first.smartdashboard.main' + } + from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } } diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/PIDEditor.java b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/PIDEditor.java index f7a0cac..8ef4991 100644 --- a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/PIDEditor.java +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/PIDEditor.java @@ -1,6 +1,8 @@ + package edu.wpi.first.smartdashboard.gui.elements; import edu.wpi.first.smartdashboard.gui.elements.bindings.AbstractTableWidget; +import edu.wpi.first.smartdashboard.livewindow.elements.Controller; import edu.wpi.first.smartdashboard.livewindow.elements.NameTag; import java.awt.*; @@ -14,101 +16,138 @@ import edu.wpi.first.smartdashboard.types.named.*; * * @author Joe Grinstead */ -public class PIDEditor extends AbstractTableWidget { - - public static final DataType[] TYPES = {PIDType.get()}; - - private NumberTableField pField; - private NumberTableField iField; - private NumberTableField dField; - private NumberTableField fField; - private NumberTableField sField; - private BooleanTableCheckBox eBox; - private JLabel pLabel; - private JLabel iLabel; - private JLabel dLabel; - private JLabel fLabel; - private JLabel sLabel; - private JLabel eLabel; - - public PIDEditor() {//TODO alert user when the robot is about reset modified PID values - setLayout(new GridBagLayout()); - - pLabel = new JLabel("P:"); - iLabel = new JLabel("I:"); - dLabel = new JLabel("D:"); - fLabel = new JLabel("F:"); - sLabel = new JLabel("Setpoint:"); - eLabel = new JLabel("Enabled:"); - pLabel.setHorizontalAlignment(JLabel.RIGHT); - iLabel.setHorizontalAlignment(JLabel.RIGHT); - dLabel.setHorizontalAlignment(JLabel.RIGHT); - fLabel.setHorizontalAlignment(JLabel.RIGHT); - sLabel.setHorizontalAlignment(JLabel.RIGHT); - eLabel.setHorizontalAlignment(JLabel.RIGHT); - - pField = new NumberTableField("p"); - iField = new NumberTableField("i"); - dField = new NumberTableField("d"); - fField = new NumberTableField("f"); - sField = new NumberTableField("setpoint"); - eBox = new BooleanTableCheckBox("enabled"); - - int columns = 10; - pField.setColumns(columns); - iField.setColumns(columns); - dField.setColumns(columns); - fField.setColumns(columns); - sField.setColumns(columns); - - - GridBagConstraints c = new GridBagConstraints(); - - - c.gridy = 1; - add(pLabel, c); - c.gridy = 2; - add(iLabel, c); - c.gridy = 3; - add(dLabel, c); - c.gridy = 4; - add(fLabel, c); - c.gridy = 5; - add(sLabel, c); - c.gridy = 6; - add(eLabel, c); - - c.gridx = 1; - c.weightx = 1.0; - c.gridy = 0; - c.fill = GridBagConstraints.HORIZONTAL; +public class PIDEditor extends AbstractTableWidget implements Controller { + + public static final DataType[] TYPES = {PIDType.get()}; + + private static final String[] pidTypes = {"Displacement", "Rate"}; // kDisplacement, kRate + + private final boolean editType; + + private NumberTableComboBox tBox; + private NumberTableField pField; + private NumberTableField iField; + private NumberTableField dField; + private NumberTableField fField; + private NumberTableField sField; + private BooleanTableCheckBox eBox; + private JLabel tLabel; + private JLabel pLabel; + private JLabel iLabel; + private JLabel dLabel; + private JLabel fLabel; + private JLabel sLabel; + private JLabel eLabel; + + public PIDEditor() { + this(true); + } + + public PIDEditor(boolean editType) {//TODO alert user when the robot is about reset modified PID values + this.editType = editType; + } + + @Override + public void init() { + setLayout(new GridBagLayout()); + + if (editType) { + tLabel = new JLabel("PID type: "); + } + pLabel = new JLabel("P:"); + iLabel = new JLabel("I:"); + dLabel = new JLabel("D:"); + fLabel = new JLabel("F:"); + sLabel = new JLabel("Setpoint:"); + eLabel = new JLabel("Enabled:"); + if (editType) { + tLabel.setHorizontalAlignment(JLabel.RIGHT); + } + pLabel.setHorizontalAlignment(JLabel.RIGHT); + iLabel.setHorizontalAlignment(JLabel.RIGHT); + dLabel.setHorizontalAlignment(JLabel.RIGHT); + fLabel.setHorizontalAlignment(JLabel.RIGHT); + sLabel.setHorizontalAlignment(JLabel.RIGHT); + eLabel.setHorizontalAlignment(JLabel.RIGHT); + if (editType) { + tBox = new NumberTableComboBox<>("PID Type", pidTypes); + } + pField = new NumberTableField("p"); + iField = new NumberTableField("i"); + dField = new NumberTableField("d"); + fField = new NumberTableField("f"); + sField = new NumberTableField("setpoint"); + eBox = new BooleanTableCheckBox("enabled"); + + int columns = 10; + pField.setColumns(columns); + iField.setColumns(columns); + dField.setColumns(columns); + fField.setColumns(columns); + sField.setColumns(columns); + + if (editType) { + System.out.println("tbox="+tBox); + System.out.println("table="+table); + tBox.addActionListener(e -> table.putNumber("PID Type", tBox.getSelectedIndex())); + } + + GridBagConstraints c = new GridBagConstraints(); + + + c.gridy = 1; + if (editType) { + add(tLabel, c); + } + c.gridy = 2; + add(pLabel, c); + c.gridy = 3; + add(iLabel, c); + c.gridy = 4; + add(dLabel, c); + c.gridy = 5; + add(fLabel, c); + c.gridy = 6; + add(sLabel, c); + c.gridy = 7; + add(eLabel, c); + + c.gridx = 1; + c.weightx = 1.0; + c.gridy = 0; + c.fill = GridBagConstraints.HORIZONTAL; add(nameTag = new NameTag(""), c); - nameTag.setHorizontalAlignment(JLabel.LEFT); - c.gridy = 1; - add(pField, c); - c.gridy = 2; - add(iField, c); - c.gridy = 3; - add(dField, c); - c.gridy = 4; - add(fField, c); - c.gridy = 5; - add(sField, c); - c.gridy = 6; - add(eBox, c); - - setMaximumSize(new Dimension(Integer.MAX_VALUE, getPreferredSize().height)); - - revalidate(); - repaint(); - } - - @Override - public void init(){ - nameTag.setText(getFieldName()); - } - - @Override - public void propertyChanged(Property property) { - } + nameTag.setHorizontalAlignment(JLabel.LEFT); + nameTag.setText(getFieldName()); + c.gridy = 1; + if (editType) { + add(tBox, c); + } + c.gridy = 2; + add(pField, c); + c.gridy = 3; + add(iField, c); + c.gridy = 4; + add(dField, c); + c.gridy = 5; + add(fField, c); + c.gridy = 6; + add(sField, c); + c.gridy = 7; + add(eBox, c); + + setMaximumSize(new Dimension(Integer.MAX_VALUE, getPreferredSize().height)); + + revalidate(); + repaint(); + } + + @Override + public void propertyChanged(Property property) { + } + + @Override + public void reset() { + eBox.setBindableValue(false); + } } diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/bindings/AbstractTableWidget.java b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/bindings/AbstractTableWidget.java index e20b5bb..99f232a 100644 --- a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/bindings/AbstractTableWidget.java +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/bindings/AbstractTableWidget.java @@ -7,6 +7,7 @@ import edu.wpi.first.smartdashboard.types.DataType; import edu.wpi.first.wpilibj.tables.*; import java.awt.Point; import java.util.*; +import javax.swing.JComboBox; /** * An abstraction for creating a widget that wraps a network table @@ -54,12 +55,12 @@ public abstract class AbstractTableWidget extends Widget implements ITableListen if(value != null) { element.setValue(value); } - subsystem.add(element); + subsystem.addWidget(element); } - private Map booleanFields = new HashMap(); - private Map numberFields = new HashMap(); - private Map stringFields = new HashMap(); + private Map> booleanFields = new HashMap<>(); + private Map> numberFields = new HashMap<>(); + private Map> stringFields = new HashMap<>(); @Override public void valueChanged(ITable source, String key, Object value, boolean isNew) { if(value instanceof Boolean) @@ -74,19 +75,19 @@ public abstract class AbstractTableWidget extends Widget implements ITableListen public void booleanChanged(ITable source, String key, boolean value, boolean isNew) { - BooleanBindable field = booleanFields.get(key); - if(field!=null) - field.setBindableValue(value); + if(!booleanFields.containsKey(key)) booleanFields.put(key, new ArrayList<>()); + List field = booleanFields.get(key); + field.stream().forEach(bindable -> bindable.setBindableValue(value)); } public void doubleChanged(ITable source, String key, double value, boolean isNew) { - NumberBindable field = numberFields.get(key); - if(field!=null) - field.setBindableValue(value); + if(!numberFields.containsKey(key)) numberFields.put(key, new ArrayList<>()); + List field = numberFields.get(key); + field.stream().forEach(bindable -> bindable.setBindableValue(value)); } public void stringChanged(ITable source, String key, String value, boolean isNew) { - StringBindable field = stringFields.get(key); - if(field!=null) - field.setBindableValue(value); + if(!stringFields.containsKey(key)) stringFields.put(key, new ArrayList<>()); + List field = stringFields.get(key); + field.stream().forEach(bindable -> bindable.setBindableValue(value)); } public void tableChanged(ITable source, String key, ITable value, boolean isNew) { } @@ -114,20 +115,17 @@ public abstract class AbstractTableWidget extends Widget implements ITableListen protected void setBooleanBinding(String key, BooleanBindable displayer){ - if(booleanFields.containsKey(key))//TODO maybe remove and just let them overwrite??? - throw new RuntimeException("Cannot have multiple boolean fields for the same key: "+key); - booleanFields.put(key, displayer); + if(!booleanFields.containsKey(key)) booleanFields.put(key, new ArrayList<>()); + booleanFields.get(key).add(displayer); } protected void setNumberBinding(String key, NumberBindable displayer){ - if(numberFields.containsKey(key)) - throw new RuntimeException("Cannot have multiple number fields for the same key: "+key); - numberFields.put(key, displayer); + if(!numberFields.containsKey(key)) numberFields.put(key, new ArrayList<>()); + numberFields.get(key).add(displayer); } protected void setStringBinding(String key, StringBindable displayer, String defaultValue){ - if(stringFields.containsKey(key)) - throw new RuntimeException("Cannot have multiple string fields for the same key: "+key); displayer.setBindableValue(defaultValue); - stringFields.put(key, displayer); + if(!stringFields.containsKey(key)) stringFields.put(key, new ArrayList<>()); + stringFields.get(key).add(displayer); } @@ -157,4 +155,29 @@ public abstract class AbstractTableWidget extends Widget implements ITableListen setStringBinding(key, this, ""); } } + public class StringTableComboBox extends JComboBox implements StringBindable { + public StringTableComboBox(final String key, String... items) { + super(items); + getTableEntryBindable(key); + setStringBinding(key, this, ""); + addActionListener(e -> table.putString(key, (String) getSelectedItem())); + } + @Override + public void setBindableValue(String value) { + setSelectedItem(value); + } + } + public class NumberTableComboBox extends JComboBox implements NumberBindable { + public NumberTableComboBox(final String key, E... items) { + super(items); + getTableEntryBindable(key); + setNumberBinding(key, this); + addActionListener(e -> table.putNumber(key, getSelectedIndex())); + } + @Override + public void setBindableValue(double value) { + if((int) value == value && value >= 0 && value < getItemCount()) + setSelectedIndex((int) value); + } + } } diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/CANSpeedController.java b/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/CANSpeedController.java new file mode 100644 index 0000000..faad078 --- /dev/null +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/CANSpeedController.java @@ -0,0 +1,242 @@ + +package edu.wpi.first.smartdashboard.livewindow.elements; + +import edu.wpi.first.smartdashboard.gui.elements.PIDEditor; +import edu.wpi.first.smartdashboard.gui.elements.bindings.AbstractTableWidget; +import edu.wpi.first.smartdashboard.properties.Property; +import edu.wpi.first.smartdashboard.types.DataType; +import edu.wpi.first.smartdashboard.types.named.CANSpeedControllerType; +import edu.wpi.first.wpilibj.tables.ITable; + +import java.awt.CardLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionListener; +import javax.swing.JComboBox; + +import javax.swing.JPanel; + +/** + * + * @author Sam Carlberg + */ +public class CANSpeedController extends AbstractTableWidget implements Controller { + + public static final DataType[] TYPES = {CANSpeedControllerType.get()}; + + private static final String TYPE_TALON = "CANTalon"; + private static final String TYPE_JAGUAR = "CANJaguar"; + + /** + * The type of the CAN controller. + */ + private String type = ""; + /** + * The mode the CAN controller is operating in. + */ + private int mode = 0; + + private static final int TALON_DISABLED_MODE = 15; + + /** + * The modes that the CAN Talon can run in. + */ + private static final String[] talonModes = {"PercentVbus", "Position", "Speed", "Current", "Voltage", "Follower", "Disabled"}; + + /** + * The modes that the CAN Jaguar can run in. + */ + private static final String[] jaguarModes = {"PercentVbus", "Current", "Speed", "Position", "Voltage"}; + + private JComboBox talonModeBox = new JComboBox<>(talonModes); + private JComboBox jaguarModeBox = new JComboBox<>(jaguarModes); + private JComboBox modeBox = talonModeBox; + + /** + * Header panel containing the name tag and the mode combobox. + */ + private JPanel headerPanel; + + /** + * Control panel containing the PID editor / speed controller editor. + */ + private JPanel controlPanel; + private PIDEditor pidControlPanel; + private SpeedController normalControlPanel; + + private ActionListener modeSelection = e -> { + int m = modeBox.getSelectedIndex(); + if (m == 6) { + // CAN Talon mode #6 has a value of 15 + m = TALON_DISABLED_MODE; + } + normalControlPanel.reset(); + mode = m; + table.putBoolean("Enabled", mode == 0 || mode == 4); // enable on %VBus and voltage, disable on all others + table.putNumber("Mode", mode); + }; + + @Override + public void init() { + nameTag = new NameTag(getFieldName()); + headerPanel = new JPanel(); + controlPanel = new JPanel(); + createPIDControlPanel(); + createNormalControlPanel(); + controlPanel.add(normalControlPanel); + + headerPanel.setLayout(new GridBagLayout()); + GridBagConstraints headerConstraints = new GridBagConstraints(); + headerConstraints.fill = GridBagConstraints.BOTH; + headerConstraints.gridx = 0; + headerConstraints.gridy = 0; + headerPanel.add(nameTag, headerConstraints); + headerConstraints.gridx++; + headerPanel.add(modeBox, headerConstraints); + + setLayout(new GridBagLayout()); + GridBagConstraints controlConstraints = new GridBagConstraints(); + controlConstraints.gridx = 0; + controlConstraints.gridy = 0; + controlConstraints.fill = GridBagConstraints.BOTH; + add(headerPanel, controlConstraints); + controlConstraints.gridy++; + add(controlPanel, controlConstraints); + + talonModeBox.addActionListener(modeSelection); + jaguarModeBox.addActionListener(modeSelection); + } + + private void createPIDControlPanel() { + pidControlPanel = new PIDEditor(false); + pidControlPanel.setValue(this.table); + pidControlPanel.init(); + } + + private void createNormalControlPanel() { + normalControlPanel = new SpeedController(); + normalControlPanel.setValue(this.table); + normalControlPanel.init(); + } + + @Override + public void setValue(Object value) { + super.setValue(value); + pidControlPanel.setValue(value); + normalControlPanel.setValue(value); + this.type = table.getString("Type", "[unknown]"); + this.mode = (int) table.getNumber("Mode", 0); + + headerPanel.remove(modeBox); + switch (type) { + case TYPE_TALON: + modeBox = talonModeBox; + break; + case TYPE_JAGUAR: + modeBox = jaguarModeBox; + break; + } + headerPanel.add(modeBox); + modeBox.setSelectedIndex(mode == TALON_DISABLED_MODE ? 6 : mode); + setControlPanel(); + } + + @Override + public void booleanChanged(ITable source, String key, boolean value, boolean isNew) { + pidControlPanel.booleanChanged(source, key, value, isNew); + normalControlPanel.booleanChanged(source, key, value, isNew); + } + + @Override + public void doubleChanged(ITable source, String key, double value, boolean isNew) { + if ("Mode".equals(key)) { + this.mode = (int) value; + modeBox.setSelectedIndex(mode == TALON_DISABLED_MODE ? 6 : mode); + setControlPanel(); + normalControlPanel.reset(); + } + pidControlPanel.doubleChanged(source, key, value, isNew); + normalControlPanel.doubleChanged(source, key, value, isNew); + } + + @Override + public void stringChanged(ITable source, String key, String value, boolean isNew) { + if ("Type".equals(key)) { + this.type = value; + } + pidControlPanel.stringChanged(source, key, value, isNew); + normalControlPanel.stringChanged(source, key, value, isNew); + } + + @Override + public void valueChanged(ITable source, String key, Object value, boolean isNew) { + super.valueChanged(source, key, value, isNew); + pidControlPanel.valueChanged(source, key, value, isNew); + normalControlPanel.valueChanged(source, key, value, isNew); + } + + @Override + public void propertyChanged(Property property) { + pidControlPanel.propertyChanged(property); + normalControlPanel.propertyChanged(property); + } + + @Override + public void reset() { + normalControlPanel.reset(); + pidControlPanel.reset(); + } + + private void setControlPanel() { + if (mode == TALON_DISABLED_MODE || mode == 5) { + // empty (follower or disabled) + normalControlPanel.reset(); + pidControlPanel.reset(); + controlPanel.removeAll(); + controlPanel.setSize(0, 0); + } else if (isPID()) { + if (pidControlPanel.getParent() != controlPanel) { + // set control to PID and resize + normalControlPanel.reset(); + controlPanel.removeAll(); + controlPanel.add(pidControlPanel); + controlPanel.setSize(pidControlPanel.getSize()); + } + } else { + if (normalControlPanel.getParent() != controlPanel) { + // set control to normal and resize + pidControlPanel.reset(); + controlPanel.removeAll(); + controlPanel.add(normalControlPanel); + controlPanel.setSize(normalControlPanel.getSize()); + } + // set the range on the slider depending on the mode + switch(mode) { + case 0: // Percent vbus + normalControlPanel.setRange(-1, 1); + break; + case 4: // voltage + normalControlPanel.setRange(-12, 12); + break; + default: + normalControlPanel.setRange(-0.0, 0); + break; + } + } + } + + /** + * Checks if the current type and mode are PID-compatible. + */ + private boolean isPID() { + switch (type) { + case TYPE_TALON: + return mode == 1 || mode == 2 || mode == 3; // position, speed, current + case TYPE_JAGUAR: + return mode == 1 || mode == 2 || mode == 3; // current, speed, position + default: + return false; + } + } + +} diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/LiveWindowWidgetRegistrar.java b/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/LiveWindowWidgetRegistrar.java index 0faa69d..4595ba2 100644 --- a/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/LiveWindowWidgetRegistrar.java +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/LiveWindowWidgetRegistrar.java @@ -13,6 +13,7 @@ public class LiveWindowWidgetRegistrar { */ public static void init() { DisplayElementRegistry.registerWidget(LWSubsystem.class); + DisplayElementRegistry.registerWidget(PIDSubsystem.class); DisplayElementRegistry.registerWidget(SpeedController.class); DisplayElementRegistry.registerWidget(RelayController.class); DisplayElementRegistry.registerWidget(DigitalOutputController.class); @@ -23,6 +24,7 @@ public class LiveWindowWidgetRegistrar { DisplayElementRegistry.registerWidget(ServoController.class); DisplayElementRegistry.registerWidget(PowerDistributionPanel.class); DisplayElementRegistry.registerWidget(ThreeAxisAccelerometer.class); + DisplayElementRegistry.registerWidget(CANSpeedController.class); } } diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/PIDSubsystem.java b/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/PIDSubsystem.java new file mode 100644 index 0000000..fa4fe17 --- /dev/null +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/PIDSubsystem.java @@ -0,0 +1,45 @@ + +package edu.wpi.first.smartdashboard.livewindow.elements; + +import edu.wpi.first.smartdashboard.gui.elements.PIDEditor; +import edu.wpi.first.smartdashboard.types.DataType; +import edu.wpi.first.smartdashboard.types.named.PIDSubsystemType; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Sam Carlberg + */ +public class PIDSubsystem extends LWSubsystem { + + public static final DataType[] TYPES = {PIDSubsystemType.get()}; + + private PIDEditor pidController; + + @Override + public void init() { + System.out.println("PIDSubsystem init()"); + super.init(); + try { + pidController = (PIDEditor) DataType.getType("PIDController", true).getDefault().newInstance(); + pidController.setFieldName("Controller"); + pidController.setType(DataType.getType("PIDController", true)); + System.out.println("PIDSubsystem table=" + table); + pidController.setValue(table); + pidController.init(); + addWidget(pidController); + } catch (InstantiationException | IllegalAccessException ex) { + Logger.getLogger(PIDSubsystem.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + public void setValue(Object value) { + System.out.println("PIDSubsystem setValue(value=" + value + ")"); + super.setValue(value); + pidController.setValue(value); + } + +} diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/SpeedController.java b/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/SpeedController.java index bd0a779..aee670c 100644 --- a/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/SpeedController.java +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/livewindow/elements/SpeedController.java @@ -90,5 +90,10 @@ public class SpeedController extends AbstractTableWidget implements Controller { public void propertyChanged(Property property) { } + + public void setRange(double min, double max) { + controller.setMin(min); + controller.setMax(max); + } } diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/main.java b/smartdashboard/src/edu/wpi/first/smartdashboard/main.java index 2971495..296a417 100644 --- a/smartdashboard/src/edu/wpi/first/smartdashboard/main.java +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/main.java @@ -16,10 +16,10 @@ import edu.wpi.first.smartdashboard.robot.*; * @author pmalmsten */ public class main { - + /** Variable used in the {@link main#inCompetition() inCompetition()} method */ private static boolean inCompetition = false; - + /** * Returns whether or not this is in "competition" mode. Competition mode * should be used on the netbook provided for teams to use the dashboard. If @@ -33,7 +33,7 @@ public class main { public static boolean inCompetition() { return inCompetition; } - + private static DashboardFrame frame; /** @@ -56,17 +56,17 @@ public class main { ex.printStackTrace(); System.exit(2); } - + // Present a loading bar (it will only show up if this is going slowly) final ProgressMonitor monitor = new ProgressMonitor(null, "Loading SmartDashboard", "Initializing internal code...", 0, 1000); - + // Search the filesystem for extensions (49%) FileSniffer.findExtensions(monitor, 0, 490); // Parse arguments ArgParser argParser = new ArgParser(args, true, true, new String[] { "ip" }); inCompetition = argParser.hasFlag("competition"); - + // Initialize GUI try { SwingUtilities.invokeAndWait(new Runnable() { @@ -77,7 +77,7 @@ public class main { ex.printStackTrace(); System.exit(2); } - + if (argParser.hasValue("ip")) { monitor.setProgress(650); monitor.setNote("Connecting to robot at: "+argParser.getValue("ip")); @@ -98,35 +98,37 @@ public class main { } teamNumber = Integer.parseInt(input); } catch(Exception e){} - } - + } + monitor.setProgress(650); monitor.setNote("Connecting to robot of team: "+teamNumber); teamProp.setValue(teamNumber); + Robot.setUseMDNS(DashboardPrefs.getInstance().usemDNS.getValue()); + Robot.setTeam(teamNumber); } - + try { SwingUtilities.invokeAndWait(new Runnable() { - + public void run() { try { frame.pack(); frame.setVisible(true); - + monitor.setProgress(750); monitor.setNote("Loading From Save"); - + // Load File file = new File(frame.getPrefs().saveFile.getValue()); if (file.exists()) { frame.load(file.getPath()); } - + monitor.setProgress(1000); - + } catch (Exception e) { e.printStackTrace(); - + System.exit(1); } } diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/types/named/CANSpeedControllerType.java b/smartdashboard/src/edu/wpi/first/smartdashboard/types/named/CANSpeedControllerType.java new file mode 100644 index 0000000..c20fab9 --- /dev/null +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/types/named/CANSpeedControllerType.java @@ -0,0 +1,27 @@ + +package edu.wpi.first.smartdashboard.types.named; + +import edu.wpi.first.smartdashboard.livewindow.elements.CANSpeedController; +import edu.wpi.first.smartdashboard.types.NamedDataType; + +/** + * + * @author Sam Carlberg + */ +public class CANSpeedControllerType extends NamedDataType { + + public static final String LABEL = "CANSpeedController"; + + private CANSpeedControllerType() { + super(LABEL, CANSpeedController.class); + } + + public static NamedDataType get() { + if (NamedDataType.get(LABEL) != null) { + return NamedDataType.get(LABEL); + } else { + return new CANSpeedControllerType(); + } + } + +} diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/types/named/PIDSubsystemType.java b/smartdashboard/src/edu/wpi/first/smartdashboard/types/named/PIDSubsystemType.java index abcd121..610985e 100644 --- a/smartdashboard/src/edu/wpi/first/smartdashboard/types/named/PIDSubsystemType.java +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/types/named/PIDSubsystemType.java @@ -1,5 +1,6 @@ package edu.wpi.first.smartdashboard.types.named; +import edu.wpi.first.smartdashboard.livewindow.elements.PIDSubsystem; import edu.wpi.first.smartdashboard.types.NamedDataType; /** @@ -11,7 +12,7 @@ public class PIDSubsystemType extends NamedDataType { public static final String LABEL = "PIDSubsystem"; private PIDSubsystemType() { - super(LABEL, SubsystemType.get(), PIDType.get()); + super(LABEL, PIDSubsystem.class, SubsystemType.get(), PIDType.get()); } public static NamedDataType get() { -- cgit v1.2.3-54-g00ecf