├── java ├── FRC-DriverStation-Android │ ├── .gitignore │ ├── res │ │ ├── values │ │ │ ├── styles.xml │ │ │ └── strings.xml │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-ldpi │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ ├── layout │ │ │ └── fragment_operation.xml │ │ └── menu │ │ │ └── activity_main.xml │ ├── ic_launcher-web.png │ ├── .classpath │ ├── src │ │ └── org │ │ │ └── anidev │ │ │ └── frcds │ │ │ └── android │ │ │ ├── OperationFragment.java │ │ │ └── MainActivity.java │ ├── .settings │ │ └── org.eclipse.jdt.core.prefs │ ├── project.properties │ ├── proguard-project.txt │ ├── .project │ └── AndroidManifest.xml ├── mavenrepo │ └── FRCDS-Libs │ │ └── forms │ │ ├── 1.3.0 │ │ ├── forms-1.3.0.jar.md5 │ │ ├── forms-1.3.0.pom.md5 │ │ ├── forms-1.3.0-sources.jar.md5 │ │ ├── forms-1.3.0.jar.sha1 │ │ ├── forms-1.3.0.pom.sha1 │ │ ├── forms-1.3.0-sources.jar.sha1 │ │ ├── forms-1.3.0.jar │ │ ├── forms-1.3.0-sources.jar │ │ └── forms-1.3.0.pom │ │ ├── maven-metadata-local.xml.md5 │ │ ├── maven-metadata-local.xml.sha1 │ │ └── maven-metadata-local.xml ├── Utils │ ├── .settings │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.eclipse.m2e.core.prefs │ ├── .project │ ├── .classpath │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── anidev │ │ └── utils │ │ ├── GTKIconTheme.java │ │ └── Utils.java ├── FRC-Netconsole-PC │ ├── .settings │ │ ├── org.eclipse.jdt.core.prefs │ │ ├── org.eclipse.m2e.core.prefs │ │ └── org.eclipse.core.resources.prefs │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ ├── list.png │ │ │ ├── pause.png │ │ │ ├── text.png │ │ │ ├── arrow-up.png │ │ │ ├── delete.png │ │ │ └── arrow-down.png │ │ │ └── java │ │ │ └── org │ │ │ └── anidev │ │ │ └── frcds │ │ │ └── pc │ │ │ └── nc │ │ │ ├── NetconsoleMain.java │ │ │ ├── NetconsoleFrame.java │ │ │ ├── ControlBar.java │ │ │ └── NetconsolePanel.java │ ├── .project │ ├── .classpath │ └── pom.xml ├── FRCDS-Java-Comm │ ├── .settings │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.eclipse.m2e.core.prefs │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── org │ │ │ └── anidev │ │ │ └── frcds │ │ │ └── proto │ │ │ ├── DataDir.java │ │ │ ├── torobot │ │ │ ├── OperationMode.java │ │ │ ├── Alliance.java │ │ │ ├── TeamStation.java │ │ │ ├── DigitalInputs.java │ │ │ ├── CRIOChecksum.java │ │ │ ├── FPGAChecksum.java │ │ │ ├── AnalogInputs.java │ │ │ ├── Joystick.java │ │ │ └── FRCCommonControl.java │ │ │ ├── nc │ │ │ ├── NetconsoleListener.java │ │ │ ├── NetconsoleMessage.java │ │ │ └── Netconsole.java │ │ │ ├── FRCCommunicationListener.java │ │ │ ├── CommData.java │ │ │ ├── tods │ │ │ ├── DigitalOutputs.java │ │ │ ├── MacAddress.java │ │ │ └── FRCRobotControl.java │ │ │ ├── Version.java │ │ │ └── ControlFlags.java │ ├── .project │ ├── pom.xml │ └── .classpath ├── FRC-DriverStation-Common │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.eclipse.core.resources.prefs │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── org │ │ │ └── anidev │ │ │ └── frcds │ │ │ └── common │ │ │ ├── types │ │ │ └── BatteryProvider.java │ │ │ ├── CommonLoop.java │ │ │ ├── EnabledLoop.java │ │ │ └── DriverStation.java │ ├── .project │ ├── .classpath │ └── pom.xml ├── FRC-DriverStation-PC │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ ├── status-bad.png │ │ │ └── status-good.png │ │ │ └── java │ │ │ └── org │ │ │ └── anidev │ │ │ └── frcds │ │ │ └── pc │ │ │ ├── battery │ │ │ ├── win │ │ │ │ ├── Kernel32.java │ │ │ │ ├── WindowsBatteryProvider.java │ │ │ │ └── PowerStatus.java │ │ │ └── linux │ │ │ │ └── LinuxBatteryProvider.java │ │ │ ├── input │ │ │ ├── InputListener.java │ │ │ ├── Type.java │ │ │ ├── trans │ │ │ │ ├── TranslationProfile.java │ │ │ │ └── BasicTranslation.java │ │ │ ├── InputDevice.java │ │ │ └── InputEnvironment.java │ │ │ ├── gui │ │ │ ├── TeamIDPanel.java │ │ │ ├── EnableDisablePanel.java │ │ │ ├── EnhancedToggleButton.java │ │ │ ├── StatusPanel.java │ │ │ ├── OperationPanel.java │ │ │ ├── DriverStationFrame.java │ │ │ └── SetupPanel.java │ │ │ ├── PCDriverStation.java │ │ │ └── DriverStationMain.java │ ├── .project │ ├── .classpath │ └── pom.xml ├── FRCDS-PacketAnalyzer │ ├── .settings │ │ ├── org.eclipse.jdt.core.prefs │ │ ├── org.eclipse.m2e.core.prefs │ │ └── org.eclipse.core.resources.prefs │ ├── .project │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── org │ │ │ └── anidev │ │ │ └── frcds │ │ │ └── analyze │ │ │ ├── AnalyzerMain.java │ │ │ ├── FileProvider.java │ │ │ └── AnalyzerProviderSelector.java │ ├── .classpath │ └── pom.xml ├── FRC-ReceiveDS │ ├── .classpath │ ├── .project │ └── src │ │ └── org │ │ └── anidev │ │ └── frcds │ │ └── receiveds │ │ └── Main.java └── pom.xml ├── .gitignore ├── COPYING.md └── README.md /java/FRC-DriverStation-Android/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | gen/ 3 | /libs 4 | /assets 5 | -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0.jar.md5: -------------------------------------------------------------------------------- 1 | 68153fd645ffc88efdd424bf7671f37a -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0.pom.md5: -------------------------------------------------------------------------------- 1 | 330a7acbe8b2bfada7efb5c759379c65 -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/maven-metadata-local.xml.md5: -------------------------------------------------------------------------------- 1 | ba1bdb95b3e0fe51be20c2215e91c1cd -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0-sources.jar.md5: -------------------------------------------------------------------------------- 1 | 845fc4aa8639a4532b730e0347a4c81a -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0.jar.sha1: -------------------------------------------------------------------------------- 1 | e9003fc88e55a05be29e633ca09da9457bd3d5c4 -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0.pom.sha1: -------------------------------------------------------------------------------- 1 | 2db43a4086c3a8bdbad865ac12b808aa015c5013 -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/maven-metadata-local.xml.sha1: -------------------------------------------------------------------------------- 1 | b380ea274c10889730dfd48c3dc0c1b38c3301b3 -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0-sources.jar.sha1: -------------------------------------------------------------------------------- 1 | 7431613fc740853af121d5354a0d5fc6de9b6c33 -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /java/Utils/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding/=UTF-8 4 | -------------------------------------------------------------------------------- /java/Utils/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 3 | -------------------------------------------------------------------------------- /java/Utils/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-DriverStation-Android/ic_launcher-web.png -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 3 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/src/main/resources/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-Netconsole-PC/src/main/resources/list.png -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/src/main/resources/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-Netconsole-PC/src/main/resources/pause.png -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/src/main/resources/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-Netconsole-PC/src/main/resources/text.png -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding/=UTF-8 4 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 3 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/DataDir.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto; 2 | 3 | public enum DataDir { 4 | TODS,TOROBOT; 5 | } 6 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/src/main/resources/arrow-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-Netconsole-PC/src/main/resources/arrow-up.png -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/src/main/resources/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-Netconsole-PC/src/main/resources/delete.png -------------------------------------------------------------------------------- /java/FRCDS-PacketAnalyzer/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 3 | -------------------------------------------------------------------------------- /java/FRCDS-PacketAnalyzer/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0.jar -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 3 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/src/main/resources/arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-Netconsole-PC/src/main/resources/arrow-down.png -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/resources/status-bad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-DriverStation-PC/src/main/resources/status-bad.png -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/resources/status-good.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-DriverStation-PC/src/main/resources/status-good.png -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0-sources.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0-sources.jar -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-DriverStation-Android/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-DriverStation-Android/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-DriverStation-Android/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anidev/frc-driverstation/HEAD/java/FRC-DriverStation-Android/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /java/FRCDS-PacketAnalyzer/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse files 2 | .metadata 3 | *.class 4 | bin/ 5 | target/ 6 | .recommenders 7 | 8 | # Package files 9 | *.jar 10 | *.war 11 | *.ear 12 | *.zip 13 | 14 | # Backup files 15 | *~ 16 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/torobot/OperationMode.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.torobot; 2 | 3 | public enum OperationMode { 4 | TELEOPERATED,AUTONOMOUS,TEST;//PRACTICE; 5 | } 6 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/src/main/java/org/anidev/frcds/common/types/BatteryProvider.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.common.types; 2 | 3 | public interface BatteryProvider { 4 | public double getBatteryPercent(); 5 | } 6 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/battery/win/Kernel32.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.battery.win; 2 | 3 | import com.sun.jna.Library; 4 | 5 | public interface Kernel32 extends Library { 6 | public boolean GetSystemPowerStatus(PowerStatus status); 7 | } 8 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | FRC Driver Station 5 | Hello world! 6 | Settings 7 | 8 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/res/layout/fragment_operation.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/res/menu/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /java/FRC-ReceiveDS/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/nc/NetconsoleListener.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.nc; 2 | 3 | public abstract class NetconsoleListener { 4 | public void dataSent(NetconsoleMessage msg) { 5 | } 6 | public void receivedData(NetconsoleMessage msg) { 7 | } 8 | public void messagesCleared() { 9 | } 10 | public void pauseChanged(boolean paused) { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/maven-metadata-local.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | FRCDS-Libs 4 | forms 5 | 6 | 1.3.0 7 | 8 | 1.3.0 9 | 10 | 20140107234005 11 | 12 | 13 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/input/InputListener.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.input; 2 | 3 | /** 4 | * Add and remove input devices 5 | */ 6 | public abstract class InputListener { 7 | /** 8 | * @param dev the input device to add 9 | */ 10 | public void deviceAdded(InputDevice dev) { 11 | } 12 | /** 13 | * @param dev the input device to remove 14 | */ 15 | public void deviceRemoved(InputDevice dev) { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /java/FRC-ReceiveDS/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FRC-ReceiveDS 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/input/Type.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.input; 2 | 3 | /** 4 | * Type of input device 5 | */ 6 | public enum Type { 7 | // Genearlly, joysticks have 3 axes (x, y, z, 8 | // where z is rotation or throttle) 9 | // Gamepads have 4 axes (two sticks x and y), 10 | // or 6 axes (two sticks x and y, l and r triggers) 11 | // 6-axis gamepads are generally XBOX controllers 12 | JOYSTICK,GAMEPAD4,GAMEPAD6,UNKNOWN; 13 | } 14 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /java/mavenrepo/FRCDS-Libs/forms/1.3.0/forms-1.3.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | FRCDS-Libs 6 | forms 7 | 1.3.0 8 | POM was created from install:install-file 9 | 10 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/src/main/java/org/anidev/frcds/pc/nc/NetconsoleMain.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.nc; 2 | 3 | import javax.swing.JFrame; 4 | import org.anidev.frcds.proto.nc.Netconsole; 5 | import org.anidev.utils.Utils; 6 | 7 | public class NetconsoleMain { 8 | public static void main(String[] args) { 9 | Utils.setLookAndFeel(); 10 | Netconsole netconsole=new Netconsole(); 11 | NetconsoleFrame frame=new NetconsoleFrame(netconsole); 12 | frame.setLocationByPlatform(true); 13 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 14 | frame.setVisible(true); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /java/Utils/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Utils 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FRC-Netconsole-PC 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FRCDS-Java-Comm 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/src/org/anidev/frcds/android/OperationFragment.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.android; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.support.v4.app.Fragment; 8 | 9 | public class OperationFragment extends Fragment { 10 | 11 | @Override 12 | public void onCreate(Bundle savedState) { 13 | super.onCreate(savedState); 14 | } 15 | @Override 16 | public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedState) { 17 | // return inflater.inflate(R.layout.,container,false); 18 | return null; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FRC-DriverStation-PC 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /java/FRCDS-PacketAnalyzer/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FRCDS-PacketAnalyzer 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FRC-DriverStation-Common 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/torobot/Alliance.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.torobot; 2 | 3 | public enum Alliance { 4 | RED("Red",'R'),BLUE("Blue",'B'); 5 | private String name; 6 | private char id; 7 | 8 | private Alliance(String name,char id) { 9 | this.name=name; 10 | this.id=id; 11 | } 12 | 13 | public String getName() { 14 | return name; 15 | } 16 | 17 | public char getId() { 18 | return id; 19 | } 20 | 21 | public static Alliance find(char id) { 22 | switch(Character.toUpperCase(id)) { 23 | case 'R': 24 | return Alliance.RED; 25 | case 'B': 26 | return Alliance.BLUE; 27 | } 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.6 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.6 12 | -------------------------------------------------------------------------------- /java/FRCDS-PacketAnalyzer/src/main/java/org/anidev/frcds/analyze/AnalyzerMain.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.analyze; 2 | 3 | import javax.swing.JFrame; 4 | import javax.swing.UIManager; 5 | import org.anidev.frcds.analyze.gui.AnalyzerFrame; 6 | 7 | public class AnalyzerMain { 8 | public static void main(String[] args) { 9 | try { 10 | UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); 11 | } catch(Exception e) { 12 | System.err.println("Error while setting Nimbus L&F."); 13 | e.printStackTrace(); 14 | } 15 | AnalyzerFrame frame=new AnalyzerFrame(new AnalyzerProviderSelector()); 16 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 17 | frame.setVisible(true); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/src/main/java/org/anidev/frcds/common/CommonLoop.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.common; 2 | 3 | public class CommonLoop implements Runnable { 4 | private final DriverStation ds; 5 | private double hertz; 6 | private double delayMs; 7 | public CommonLoop(DriverStation ds,double hertz) { 8 | this.ds=ds; 9 | this.hertz=hertz; 10 | this.delayMs=1000.0/this.hertz; 11 | } 12 | @Override 13 | public void run() { 14 | while(!Thread.interrupted()) { 15 | doBattery(); 16 | ds.doCommonLoopImpl(); 17 | try { 18 | Thread.sleep((long)delayMs); 19 | } catch(InterruptedException e) { 20 | break; 21 | } 22 | } 23 | } 24 | private void doBattery() { 25 | ds.refreshBattery(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/torobot/TeamStation.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.torobot; 2 | 3 | 4 | public enum TeamStation { 5 | RED1(Alliance.RED,1), 6 | RED2(Alliance.RED,2), 7 | RED3(Alliance.RED,3), 8 | BLUE1(Alliance.BLUE,1), 9 | BLUE2(Alliance.BLUE,2), 10 | BLUE3(Alliance.BLUE,3); 11 | 12 | private Alliance alliance; 13 | private int position; 14 | 15 | private TeamStation(Alliance alliance,int position) { 16 | this.alliance=alliance; 17 | this.position=position; 18 | } 19 | 20 | public Alliance getAlliance() { 21 | return alliance; 22 | } 23 | 24 | public int getPosition() { 25 | return position; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return alliance.getName()+" "+position; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-16 15 | android.library.reference.1=../../../../android/android-joystick 16 | android.library.reference.2=../../../../android/ActionBarSherlock/library 17 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/FRCCommunicationListener.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto; 2 | 3 | import org.anidev.frcds.proto.tods.FRCRobotControl; 4 | import org.anidev.frcds.proto.torobot.FRCCommonControl; 5 | 6 | /** 7 | * Listener interface for receiving data processed by the FRCCommunication 8 | * class. It can be used for receiving data from both the robot and the driver 9 | * station. 10 | * 11 | * @author Anirudh Bagde 12 | */ 13 | public interface FRCCommunicationListener { 14 | /** 15 | * Called when data is received and deserialized. 16 | * 17 | * @param data 18 | * The parsed data object. This will probably be either 19 | * {@link FRCCommonControl} or {@link FRCRobotControl}. 20 | */ 21 | public void receivedData(CommData data); 22 | } 23 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/src/main/java/org/anidev/frcds/pc/nc/NetconsoleFrame.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.nc; 2 | 3 | import java.awt.Dimension; 4 | import java.awt.event.WindowAdapter; 5 | import java.awt.event.WindowEvent; 6 | import javax.swing.JFrame; 7 | import org.anidev.frcds.proto.nc.Netconsole; 8 | 9 | public class NetconsoleFrame extends JFrame { 10 | private final Netconsole nc; 11 | private final NetconsolePanel netconsolePanel; 12 | 13 | public NetconsoleFrame(Netconsole _nc) { 14 | super("FRC Netconsole"); 15 | this.nc=_nc; 16 | setSize(new Dimension(630,300)); 17 | netconsolePanel=new NetconsolePanel(nc,true); 18 | setContentPane(netconsolePanel); 19 | addWindowListener(new WindowAdapter() { 20 | @Override 21 | public void windowClosing(WindowEvent e) { 22 | netconsolePanel.firePanelDestroyed(); 23 | } 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/src/org/anidev/frcds/android/MainActivity.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.android; 2 | 3 | import android.os.Bundle; 4 | import com.actionbarsherlock.app.ActionBar; 5 | import com.actionbarsherlock.app.SherlockFragmentActivity; 6 | import com.actionbarsherlock.view.Menu; 7 | 8 | public class MainActivity extends SherlockFragmentActivity { 9 | 10 | @Override 11 | protected void onCreate(Bundle savedState) { 12 | super.onCreate(savedState); 13 | ActionBar actionBar=getSupportActionBar(); 14 | actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 15 | actionBar.setDisplayOptions(0); 16 | } 17 | 18 | @Override 19 | public boolean onCreateOptionsMenu(Menu menu) { 20 | // Inflate the menu; this adds items to the action bar if it is present. 21 | getSupportMenuInflater().inflate(R.menu.activity_main,menu); 22 | return true; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/nc/NetconsoleMessage.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.nc; 2 | 3 | import java.util.Calendar; 4 | import org.anidev.frcds.proto.DataDir; 5 | 6 | public class NetconsoleMessage { 7 | private final DataDir dir; 8 | private final String message; 9 | private final Calendar date; 10 | 11 | public NetconsoleMessage(DataDir dir,String message) { 12 | this.dir=dir; 13 | this.message=message; 14 | this.date=Calendar.getInstance(); 15 | date.setTimeInMillis(System.currentTimeMillis()); 16 | } 17 | public NetconsoleMessage(DataDir dir,String message,Calendar date) { 18 | this.dir=dir; 19 | this.message=message; 20 | this.date=date; 21 | } 22 | 23 | public DataDir getDirection() { 24 | return dir; 25 | } 26 | 27 | public String getMessage() { 28 | return message; 29 | } 30 | 31 | public Calendar getDate() { 32 | return date; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/src/main/java/org/anidev/frcds/common/EnabledLoop.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.common; 2 | 3 | public class EnabledLoop implements Runnable { 4 | private final DriverStation ds; 5 | private long startTime=System.currentTimeMillis(); 6 | private double hertz; 7 | private double delayMs; 8 | public EnabledLoop(DriverStation ds,double hertz) { 9 | this.ds=ds; 10 | this.hertz=hertz; 11 | this.delayMs=1000.0/this.hertz; 12 | } 13 | @Override 14 | public void run() { 15 | while(!Thread.interrupted()) { 16 | doElapsedTime(); 17 | ds.doEnabledLoopImpl(); 18 | doSendData(); 19 | try { 20 | Thread.sleep((long)delayMs); 21 | } catch(InterruptedException e) { 22 | break; 23 | } 24 | } 25 | } 26 | private void doElapsedTime() { 27 | long elapsedTime=System.currentTimeMillis()-startTime; 28 | ds.setElapsedTime(elapsedTime); 29 | } 30 | private void doSendData() { 31 | ds.sendControlData(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FRC-DriverStation-Android 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /COPYING.md: -------------------------------------------------------------------------------- 1 | FRC Driver Station - free and open source implementation of an FRC driver station and communication protocol. 2 | Copyright (c) 2013, Anirudh Bagde 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | Following is copyright information for resource files. 18 | 19 | arrow-up.png, arrow-down.png, status-bad.png, status-good.png 20 | These icons are part of Oxygen Icons, used and distributed 21 | here under the terms of the GNU LGPL. 22 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | FRCDS 6 | parent 7 | 0.2 8 | 9 | Java-Comm 10 | FRCDS Java Communication 11 | 1.0 12 | FRCDS network communication library, written in Java 13 | 14 | 15 | 16 | maven-compiler-plugin 17 | 3.1 18 | 19 | 1.7 20 | 1.7 21 | 22 | 23 | 24 | 25 | 26 | 27 | FRCDS 28 | Utils 29 | 2.0 30 | 31 | 32 | -------------------------------------------------------------------------------- /java/Utils/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /java/FRCDS-PacketAnalyzer/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | FRCDS 6 | parent 7 | 0.2 8 | 9 | DriverStation-Common 10 | 0.3 11 | FRC DriverStation Common 12 | Common classes for creating a driver station program using the FRCDS communication library 13 | 14 | 15 | 16 | maven-compiler-plugin 17 | 3.1 18 | 19 | 1.7 20 | 1.7 21 | 22 | 23 | 24 | 25 | 26 | 27 | FRCDS 28 | Java-Comm 29 | 1.0 30 | 31 | 32 | -------------------------------------------------------------------------------- /java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | FRCDS 5 | parent 6 | 0.2 7 | pom 8 | 9 | 10 | 11 | mavenrepo 12 | file://${project.basedir}/../mavenrepo 13 | 14 | 15 | 16 | 17 | UTF-8 18 | ${project.basedir}/../bin 19 | 20 | 21 | 22 | Utils 23 | FRCDS-Java-Comm 24 | FRCDS-PacketAnalyzer 25 | FRC-Netconsole-PC 26 | FRC-DriverStation-Common 27 | FRC-DriverStation-PC 28 | 29 | 30 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/battery/win/WindowsBatteryProvider.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.battery.win; 2 | 3 | import org.anidev.frcds.common.types.BatteryProvider; 4 | import com.sun.jna.Native; 5 | 6 | public class WindowsBatteryProvider implements BatteryProvider { 7 | private Kernel32 kernel32=null; 8 | 9 | public WindowsBatteryProvider() { 10 | try { 11 | kernel32=(Kernel32)Native.loadLibrary("kernel32",Kernel32.class); 12 | } catch(UnsatisfiedLinkError e) { 13 | e.printStackTrace(); 14 | System.err.println("Windows battery status will be unavailable."); 15 | } 16 | } 17 | 18 | @Override 19 | public double getBatteryPercent() { 20 | if(kernel32==null) { 21 | return -1.0; 22 | } 23 | PowerStatus status=new PowerStatus(); 24 | kernel32.GetSystemPowerStatus(status); 25 | int flagByte=status.getBatteryFlag(); 26 | int percentByte=status.getBatteryLifePercent(); 27 | if(flagByte==128/*No battery*/||flagByte==255/*Unknown*/) { 28 | return -1.0; 29 | } 30 | if(percentByte==255/*Unknown*/) { 31 | return -1.0; 32 | } 33 | double percent=percentByte*1.0/100.0; 34 | return percent; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/Utils/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | FRCDS 6 | parent 7 | 0.2 8 | 9 | Utils 10 | Utils 11 | 2.0 12 | Misc common functions used by FRCDS classes 13 | 14 | 15 | 16 | maven-compiler-plugin 17 | 3.1 18 | 19 | 1.7 20 | 1.7 21 | 22 | 23 | 24 | 25 | 26 | 27 | net.java.dev.jna 28 | jna 29 | 4.0.0 30 | 31 | 32 | com.kitfox.svg 33 | svg-salamander 34 | 1.0 35 | 36 | 37 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/CommData.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto; 2 | 3 | import java.nio.ByteOrder; 4 | 5 | public abstract class CommData { 6 | public static int SIZE=-1; 7 | public static final ByteOrder BYTE_ORDER=ByteOrder.BIG_ENDIAN; 8 | 9 | public abstract byte[] serialize(); 10 | 11 | public abstract void deserialize(byte[] data); 12 | 13 | @Override 14 | public abstract int hashCode(); 15 | 16 | @Override 17 | public abstract boolean equals(Object obj); 18 | 19 | protected int boolToInt(boolean bool) { 20 | return(bool?1:0); 21 | } 22 | 23 | protected boolean intToBool(int bool) { 24 | return(bool>0?true:false); 25 | } 26 | 27 | protected int[] bitsToInts(boolean[] bits) { 28 | int numInts=(int)Math.ceil(bits.length/8.0); 29 | int[] data=new int[numInts]; 30 | for(int i=0;i>(7-b))); 43 | } 44 | } 45 | return bools; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /java/FRCDS-PacketAnalyzer/src/main/java/org/anidev/frcds/analyze/FileProvider.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.analyze; 2 | 3 | import java.awt.Component; 4 | import java.io.File; 5 | import java.io.IOException; 6 | import java.util.Scanner; 7 | import javax.swing.JFileChooser; 8 | 9 | @SuppressWarnings("unused") 10 | public class FileProvider { 11 | private static final String KDIALOG="kdialog --getopenfilename ~"; 12 | private static final String ZENITY="zenity --file-selection"; 13 | private static Runtime runtime=null; 14 | public static File askForFile(Component parent) { 15 | // if(runtime==null) { 16 | // runtime=Runtime.getRuntime(); 17 | // } 18 | // String filename=tryProcessSelection(KDIALOG); 19 | // if(filename==null) { 20 | // filename=tryProcessSelection(ZENITY); 21 | // } 22 | JFileChooser chooser=new JFileChooser(); 23 | int ret=chooser.showOpenDialog(parent); 24 | if(ret==JFileChooser.APPROVE_OPTION) { 25 | return chooser.getSelectedFile(); 26 | } 27 | return null; 28 | } 29 | private static String tryProcessSelection(String cmdline) { 30 | try { 31 | Process proc=runtime.exec(cmdline); 32 | if(proc.exitValue()!=0) { 33 | return null; 34 | } 35 | Scanner inputScanner=new Scanner(proc.getInputStream()); 36 | String filename=inputScanner.nextLine(); 37 | inputScanner.close(); 38 | return filename; 39 | } catch(IOException e) { 40 | e.printStackTrace(); 41 | return null; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/torobot/DigitalInputs.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.torobot; 2 | 3 | import java.util.Arrays; 4 | import org.anidev.frcds.proto.CommData; 5 | 6 | public class DigitalInputs extends CommData { 7 | public static final int SIZE=1; 8 | private boolean[] inputs=new boolean[] {true,true,true,true,true,true,true,true}; 9 | 10 | public boolean getInput(int index) { 11 | return inputs[index]; 12 | } 13 | 14 | public void setInput(int index,boolean value) { 15 | inputs[index]=value; 16 | } 17 | 18 | public int getNumInputs() { 19 | return inputs.length; 20 | } 21 | 22 | @Override 23 | public byte[] serialize() { 24 | int data=bitsToInts(inputs)[0]; 25 | return new byte[] {(byte)data}; 26 | } 27 | 28 | @Override 29 | public void deserialize(byte[] data) { 30 | boolean[] inputBits=intsToBits(new int[] {data[0]&0xFF}); 31 | this.inputs=inputBits; 32 | } 33 | 34 | @Override 35 | public int hashCode() { 36 | final int prime=31; 37 | int result=1; 38 | result=prime*result+Arrays.hashCode(inputs); 39 | return result; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object obj) { 44 | if(this==obj) { 45 | return true; 46 | } 47 | if(obj==null) { 48 | return false; 49 | } 50 | if(getClass()!=obj.getClass()) { 51 | return false; 52 | } 53 | DigitalInputs other=(DigitalInputs)obj; 54 | if(!Arrays.equals(inputs,other.inputs)) { 55 | return false; 56 | } 57 | return true; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/tods/DigitalOutputs.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.tods; 2 | 3 | import java.util.Arrays; 4 | import org.anidev.frcds.proto.CommData; 5 | 6 | public class DigitalOutputs extends CommData { 7 | public static final int SIZE=1; 8 | private boolean[] outputs=new boolean[] {false,false,false,false,false, 9 | false,false,false}; 10 | 11 | public boolean getInput(int index) { 12 | return outputs[index]; 13 | } 14 | 15 | public void setInput(int index,boolean value) { 16 | outputs[index]=value; 17 | } 18 | 19 | public int getNumInputs() { 20 | return outputs.length; 21 | } 22 | 23 | @Override 24 | public byte[] serialize() { 25 | int data=bitsToInts(outputs)[0]; 26 | return new byte[] {(byte)data}; 27 | } 28 | 29 | @Override 30 | public void deserialize(byte[] data) { 31 | boolean[] inputBits=intsToBits(new int[] {data[0]&0xFF}); 32 | this.outputs=inputBits; 33 | } 34 | 35 | @Override 36 | public int hashCode() { 37 | final int prime=31; 38 | int result=1; 39 | result=prime*result+Arrays.hashCode(outputs); 40 | return result; 41 | } 42 | 43 | @Override 44 | public boolean equals(Object obj) { 45 | if(this==obj) { 46 | return true; 47 | } 48 | if(obj==null) { 49 | return false; 50 | } 51 | if(getClass()!=obj.getClass()) { 52 | return false; 53 | } 54 | DigitalOutputs other=(DigitalOutputs)obj; 55 | if(!Arrays.equals(outputs,other.outputs)) { 56 | return false; 57 | } 58 | return true; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/torobot/CRIOChecksum.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.torobot; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.LongBuffer; 5 | import org.anidev.frcds.proto.CommData; 6 | 7 | public class CRIOChecksum extends CommData { 8 | public static final int SIZE=8; 9 | private long checksum; 10 | 11 | public long getChecksum() { 12 | return checksum; 13 | } 14 | 15 | public void setChecksum(long checksum) { 16 | this.checksum=checksum; 17 | } 18 | 19 | @Override 20 | public byte[] serialize() { 21 | ByteBuffer buffer=ByteBuffer.allocate(8); 22 | buffer.order(BYTE_ORDER); 23 | buffer.putLong(checksum); 24 | return buffer.array(); 25 | } 26 | 27 | @Override 28 | public void deserialize(byte[] data) { 29 | ByteBuffer byteBuffer=ByteBuffer.wrap(data); 30 | byteBuffer.order(BYTE_ORDER); 31 | LongBuffer longBuffer=byteBuffer.asLongBuffer(); 32 | checksum=longBuffer.get(0); 33 | } 34 | 35 | @Override 36 | public int hashCode() { 37 | final int prime=31; 38 | int result=1; 39 | result=prime*result+(int)(checksum^(checksum>>>32)); 40 | return result; 41 | } 42 | 43 | @Override 44 | public boolean equals(Object obj) { 45 | if(this==obj) { 46 | return true; 47 | } 48 | if(obj==null) { 49 | return false; 50 | } 51 | if(getClass()!=obj.getClass()) { 52 | return false; 53 | } 54 | CRIOChecksum other=(CRIOChecksum)obj; 55 | if(checksum!=other.checksum) { 56 | return false; 57 | } 58 | return true; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/tods/MacAddress.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.tods; 2 | 3 | import java.net.NetworkInterface; 4 | import java.net.SocketException; 5 | import java.util.Arrays; 6 | import org.anidev.frcds.proto.CommData; 7 | 8 | public class MacAddress extends CommData { 9 | public static final int SIZE=6; 10 | private byte[] macAddress=new byte[] {0,0,0,0,0,0}; 11 | 12 | public MacAddress() { 13 | try { 14 | macAddress=NetworkInterface.getNetworkInterfaces().nextElement() 15 | .getHardwareAddress(); 16 | } catch (SocketException e) { 17 | e.printStackTrace(); 18 | } 19 | } 20 | 21 | public byte[] getAddressBytes() { 22 | return macAddress; 23 | } 24 | 25 | public void setAddressBytes(byte[] macAddress) { 26 | this.macAddress=macAddress; 27 | } 28 | 29 | @Override 30 | public byte[] serialize() { 31 | return macAddress; 32 | } 33 | 34 | @Override 35 | public void deserialize(byte[] data) { 36 | macAddress=data; 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | final int prime=31; 42 | int result=1; 43 | result=prime*result+Arrays.hashCode(macAddress); 44 | return result; 45 | } 46 | 47 | @Override 48 | public boolean equals(Object obj) { 49 | if(this==obj) { 50 | return true; 51 | } 52 | if(obj==null) { 53 | return false; 54 | } 55 | if(getClass()!=obj.getClass()) { 56 | return false; 57 | } 58 | MacAddress other=(MacAddress)obj; 59 | if(!Arrays.equals(macAddress,other.macAddress)) { 60 | return false; 61 | } 62 | return true; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/battery/win/PowerStatus.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.battery.win; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import com.sun.jna.Structure; 6 | 7 | public class PowerStatus extends Structure { 8 | public final byte ACLineStatus; 9 | public final byte BatteryFlag; 10 | public final byte BatteryLifePercent; 11 | public final byte Reserved1; 12 | public final int BatteryLifeTime; 13 | public final int BatteryFullLifeTime; 14 | private List fieldOrder=null; 15 | { 16 | ACLineStatus=0; 17 | BatteryFlag=0; 18 | BatteryLifePercent=0; 19 | Reserved1=0; 20 | BatteryLifeTime=0; 21 | BatteryFullLifeTime=0; 22 | } 23 | 24 | public PowerStatus() { 25 | } 26 | 27 | @Override 28 | protected List getFieldOrder() { 29 | if(fieldOrder==null) { 30 | String[] fields=new String[] {"ACLineStatus","BatteryFlag", 31 | "BatteryLifePercent","Reserved1","BatteryLifeTime", 32 | "BatteryFullLifeTime"}; 33 | fieldOrder=Arrays.asList(fields); 34 | } 35 | return fieldOrder; 36 | } 37 | 38 | public int getACLineStatus() { 39 | return ACLineStatus&0xFF; 40 | } 41 | 42 | public int getBatteryFlag() { 43 | return BatteryFlag&0xFF; 44 | } 45 | 46 | public int getBatteryLifePercent() { 47 | return BatteryLifePercent&0xFF; 48 | } 49 | 50 | public int getReserved1() { 51 | return Reserved1&0xFF; 52 | } 53 | 54 | public long getBatteryLifeTime() { 55 | return BatteryLifeTime&(1l<<32); 56 | } 57 | 58 | public long getBatteryFullLifeTime() { 59 | return BatteryFullLifeTime&(1l<<32); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/torobot/FPGAChecksum.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.torobot; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.IntBuffer; 5 | import java.util.Arrays; 6 | import org.anidev.frcds.proto.CommData; 7 | 8 | public class FPGAChecksum extends CommData { 9 | public static final int SIZE=16; 10 | int[] checksum=new int[] {0,0,0,0}; 11 | 12 | public int[] getChecksum() { 13 | return checksum; 14 | } 15 | 16 | public void setChecksum(int[] checksum) { 17 | this.checksum=checksum; 18 | } 19 | 20 | @Override 21 | public byte[] serialize() { 22 | ByteBuffer buffer=ByteBuffer.allocate(16); 23 | buffer.order(BYTE_ORDER); 24 | for(int i=0;i identList=Arrays.asList(idents); 67 | int total=0; 68 | for(Component component:components) { 69 | if(identList.contains(component.getIdentifier())) { 70 | total++; 71 | } 72 | } 73 | return total; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | FRCDS 6 | parent 7 | 0.2 8 | 9 | Netconsole-PC 10 | 11 | FRCDS Netconsole for PC 12 | Netconsole GUI for PC driver station 13 | 14 | 15 | 16 | maven-compiler-plugin 17 | 3.1 18 | 19 | 1.7 20 | 1.7 21 | 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-shade-plugin 26 | 1.6 27 | 28 | 29 | package 30 | 31 | shade 32 | 33 | 34 | 35 | 37 | org.anidev.frcds.pc.nc.NetconsoleMain 38 | 39 | 40 | 41 | 42 | *:* 43 | 44 | META-INF/*.SF 45 | META-INF/*.DSA 46 | META-INF/*.RSA 47 | 48 | 49 | 50 | ${project.bindir}/netconsole.jar 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | FRCDS 60 | Java-Comm 61 | 1.0 62 | 63 | 64 | FRCDS 65 | Utils 66 | 2.0 67 | 68 | 69 | -------------------------------------------------------------------------------- /java/FRCDS-PacketAnalyzer/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | FRCDS 6 | parent 7 | 0.2 8 | 9 | PacketAnalyzer 10 | FRCDS Packet Analyzer 11 | 1.0 12 | Simple Java program for analyzing FRCDS packets in realtime off the network or from a file 13 | 14 | 15 | 16 | maven-compiler-plugin 17 | 3.1 18 | 19 | 1.7 20 | 1.7 21 | 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-shade-plugin 26 | 1.6 27 | 28 | 29 | package 30 | 31 | shade 32 | 33 | 34 | 35 | 37 | org.anidev.frcds.analyze.AnalyzerMain 38 | 39 | 40 | 41 | 42 | *:* 43 | 44 | META-INF/*.SF 45 | META-INF/*.DSA 46 | META-INF/*.RSA 47 | 48 | 49 | 50 | ${project.bindir}/analyzer.jar 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | FRCDS 60 | Java-Comm 61 | 1.0 62 | 63 | 64 | FRCDS-Libs 65 | forms 66 | 1.3.0 67 | 68 | 69 | -------------------------------------------------------------------------------- /java/FRC-Netconsole-PC/src/main/java/org/anidev/frcds/pc/nc/ControlBar.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.nc; 2 | 3 | import javax.swing.JToolBar; 4 | import javax.swing.SwingConstants; 5 | import java.awt.Dimension; 6 | import java.awt.event.ActionEvent; 7 | import java.awt.event.ActionListener; 8 | import java.awt.event.ItemEvent; 9 | import java.awt.event.ItemListener; 10 | import javax.swing.JButton; 11 | import org.anidev.frcds.proto.nc.Netconsole; 12 | import org.anidev.utils.Utils; 13 | import javax.swing.ButtonGroup; 14 | import javax.swing.JToggleButton; 15 | 16 | public class ControlBar extends JToolBar { 17 | private NetconsolePanel ncPanel; 18 | private Netconsole nc; 19 | private JToggleButton listButton; 20 | private JToggleButton textButton; 21 | private JToggleButton pauseButton; 22 | 23 | public ControlBar() { 24 | setBorder(null); 25 | setRollover(true); 26 | setSize(new Dimension(22,200)); 27 | setOrientation(SwingConstants.VERTICAL); 28 | 29 | JButton clearButton=new JButton(Utils.getIcon("delete.png")); 30 | clearButton.addActionListener(new ActionListener() { 31 | @Override 32 | public void actionPerformed(ActionEvent e) { 33 | nc.clearMessages(); 34 | } 35 | }); 36 | add(clearButton); 37 | 38 | pauseButton=new JToggleButton(Utils.getIcon("pause.png")); 39 | pauseButton.addItemListener(new ItemListener() { 40 | @Override 41 | public void itemStateChanged(ItemEvent e) { 42 | ncPanel.setPaused(pauseButton.isSelected()); 43 | } 44 | }); 45 | add(pauseButton); 46 | 47 | addSeparator(); 48 | 49 | listButton=new JToggleButton(Utils.getIcon("list.png")); 50 | listButton.addItemListener(new ItemListener() { 51 | @Override 52 | public void itemStateChanged(ItemEvent e) { 53 | ncPanel.setListMode(listButton.isSelected()); 54 | } 55 | }); 56 | add(listButton); 57 | 58 | textButton=new JToggleButton(Utils.getIcon("text.png")); 59 | add(textButton); 60 | 61 | ButtonGroup modeGroup=new ButtonGroup(); 62 | modeGroup.add(listButton); 63 | modeGroup.add(textButton); 64 | } 65 | 66 | protected void setPanel(NetconsolePanel ncPanel) { 67 | this.ncPanel=ncPanel; 68 | } 69 | 70 | protected void setNetconsole(Netconsole nc) { 71 | this.nc=nc; 72 | } 73 | 74 | protected JToggleButton getListButton() { 75 | return listButton; 76 | } 77 | 78 | protected JToggleButton getTextButton() { 79 | return textButton; 80 | } 81 | protected JToggleButton getPauseButton() { 82 | return pauseButton; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/input/trans/BasicTranslation.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.input.trans; 2 | 3 | import java.util.ArrayList; 4 | import net.java.games.input.Component; 5 | import net.java.games.input.Controller; 6 | 7 | /** 8 | * @formatter:off 9 | * Translation for stuff common to all input types. 10 | * Specifically translates: 11 | * - Axes 1,2,3 (which are X,Y,RZ) 12 | * TODO testing to figure this translation stuff out 13 | */ 14 | // @formatter:on 15 | 16 | // Actually, for now just present axes in the 17 | // order in which they appear? 18 | /** 19 | * Basic controller translation 20 | */ 21 | public class BasicTranslation extends TranslationProfile { 22 | protected Component[] axes; 23 | protected Component[] buttons; 24 | 25 | /** 26 | * Create a translation with the axes and buttons of the controller 27 | * @param controller the controller to create translation for 28 | */ 29 | public BasicTranslation(Controller controller) { 30 | this.controller=controller; 31 | Component[] components=controller.getComponents(); 32 | ArrayList axesList=new ArrayList<>(); 33 | ArrayList buttonList=new ArrayList<>(); 34 | for(Component component:components) { 35 | Component.Identifier ident=component.getIdentifier(); 36 | if(ident instanceof Component.Identifier.Axis) { 37 | axesList.add(component); 38 | } else { 39 | buttonList.add(component); 40 | } 41 | } 42 | this.axes=axesList.toArray(new Component[axesList.size()]); 43 | this.buttons=buttonList.toArray(new Component[buttonList.size()]); 44 | } 45 | 46 | /* (non-Javadoc) 47 | * @see org.anidev.frcds.pc.input.trans.TranslationProfile#getRawAxis(int) 48 | */ 49 | @Override 50 | public float getRawAxis(int axis) { 51 | if(axis>=getNumSupportedAxes()) { 52 | return 0.0f; 53 | } 54 | return axes[axis].getPollData(); 55 | } 56 | 57 | /* (non-Javadoc) 58 | * @see org.anidev.frcds.pc.input.trans.TranslationProfile#getButton(int) 59 | */ 60 | @Override 61 | public boolean getButton(int button) { 62 | if(button>=getNumSupportedButtons()) { 63 | return false; 64 | } 65 | return buttons[button].getPollData()>0.5f; 66 | } 67 | 68 | /* (non-Javadoc) 69 | * @see org.anidev.frcds.pc.input.trans.TranslationProfile#getNumSupportedAxes() 70 | */ 71 | @Override 72 | public int getNumSupportedAxes() { 73 | return axes.length; 74 | } 75 | 76 | /* (non-Javadoc) 77 | * @see org.anidev.frcds.pc.input.trans.TranslationProfile#getNumSupportedButtons() 78 | */ 79 | @Override 80 | public int getNumSupportedButtons() { 81 | // TODO Auto-generated method stub 82 | return buttons.length; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FRC Driver Station 2 | ================= 3 | 4 | Java implementation of the FRC driver station and communication protocol, initially in Java and later in other 5 | languages. Java was chosen because it can be ported easily to other platforms, with Android being the next goal. 6 | The entire project uses the Maven build system for compiling and packaging. To build the entire project from 7 | scratch and create the JAR files, run "mvn clean compile package" from the java/ subdirectory, or from an 8 | individual project directory to compile and package just that project. Everything can also be imported into 9 | Eclipse and compiled from there (with the m2eclipse plugin). 10 | 11 | Currently, FRCDS-Java-Comm is the Java library for the communication protocol. It implements classes for encapsulating 12 | data that can be sent from the driver station to the robot (FRCCommonControl), and data that can be sent from the 13 | robot to the driver station (FRCRobotControl) though that protocol hasn't been fully reversed yet. Each of these two 14 | classes contain fields for simple data and other classes for more complicated types of data, some of which are shared 15 | between the two protocols. Each of these classes including the two main classes all extend CommData and all implement 16 | methods for serializing directly to a byte array and deserializing directly from a byte array, as well as automatically 17 | generated equals and hashCode methods. Also included is a class that takes care of all the network communication that 18 | sends and receives data on dedicated threads so the main flow of the program isn't interrupted. 19 | 20 | FRC-DriverStation-Common contains a few classes for implementing a driver station on any platform. The two main classes 21 | it contains are an abstract class to encapsulate the driver station and a class that is meant to be run in a 22 | dedicated loop and performs such actions as incrementing the elapsed time counter and sending data packets at a 23 | given frequency (default 50.0Hz). 24 | 25 | FRC-DriverStation-PC is the driver station implementation for PC. It uses the classes in Common and builds a GUI 26 | around it. The GUI is powered by Swing, using the Nimbus L&F. It uses the JGoodies FormLayout for laying out certain 27 | GUI components. FormLayout is included in this repository and is automatically used by Maven when building. 28 | 29 | FRC-Netconsole-PC contains the GUI-related classes for Netconsole. It generates the standalone netconsole JAR file, and 30 | is used by FRC-DriverStation-PC to provide an embedded Netconsole panel. 31 | 32 | FRC-DriverStation-Android is the driver station implementation for Android. It also uses the classes in Common and builds 33 | an Android app around it. The app is targeted for 4.1.2 Jellybean (API 16) and has compliance down to 2.3.3 Gingerbread 34 | (API 9). It uses ActionBarSherlock to achieve a consistent look down to Gingerbread and android-joystick to provide onscreen 35 | joysticks. 36 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/input/InputDevice.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.input; 2 | 3 | import net.java.games.input.Component; 4 | import net.java.games.input.Controller; 5 | import org.anidev.frcds.pc.input.trans.BasicTranslation; 6 | import org.anidev.frcds.pc.input.trans.TranslationProfile; 7 | import org.anidev.frcds.proto.torobot.Joystick; 8 | 9 | /** 10 | * Device that gives input to the driver station 11 | */ 12 | public class InputDevice { 13 | private final Type type; 14 | private final Controller controller; 15 | private TranslationProfile trans; 16 | 17 | /** 18 | * @param controller the controller to pass to the super constructor 19 | */ 20 | public InputDevice(Controller controller) { 21 | this(controller,null); 22 | } 23 | 24 | /** 25 | * @param controller the controller that is being used for the driver station 26 | * @param trans the translation profile for the input device 27 | */ 28 | public InputDevice(Controller controller,TranslationProfile trans) { 29 | this.controller=controller; 30 | this.trans=trans; 31 | this.type=determineType(controller); 32 | if(trans==null) { 33 | this.trans=getTranslationForType(this.controller,this.type); 34 | } 35 | } 36 | 37 | /** 38 | * @return the type of input device 39 | */ 40 | public Type getType() { 41 | return type; 42 | } 43 | 44 | /** 45 | * @return the controller that is being used for the driver station 46 | */ 47 | public Controller getController() { 48 | return controller; 49 | } 50 | 51 | /** 52 | * @return the translation profile for the input device 53 | */ 54 | public TranslationProfile getTranslation() { 55 | return trans; 56 | } 57 | 58 | /** 59 | * @param joy the joystick to populate 60 | */ 61 | public void populateJoystick(Joystick joy) { 62 | trans.populateJoystick(joy); 63 | } 64 | 65 | /** 66 | * @param controller the controller to determine the type of 67 | * @return the type of the controller 68 | */ 69 | public static Type determineType(Controller controller) { 70 | if(controller.getType()==Controller.Type.STICK) { 71 | return Type.JOYSTICK; 72 | } 73 | Component[] components=controller.getComponents(); 74 | int numAxes=0; 75 | for(Component component:components) { 76 | Component.Identifier id=component.getIdentifier(); 77 | if((id instanceof Component.Identifier.Axis) 78 | &&id!=Component.Identifier.Axis.POV) { 79 | numAxes++; 80 | } 81 | } 82 | if(numAxes==4) { 83 | return Type.GAMEPAD4; 84 | } else if(numAxes==6) { 85 | return Type.GAMEPAD6; 86 | } 87 | return Type.UNKNOWN; 88 | } 89 | 90 | /** 91 | * @param controller the controller to get a translation profile for 92 | * @param type the Type 93 | * @return a TranslationProfile for the controller 94 | */ 95 | public static TranslationProfile getTranslationForType(Controller controller,Type type) { 96 | return new BasicTranslation(controller); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/torobot/Joystick.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.torobot; 2 | 3 | import java.util.Arrays; 4 | import org.anidev.frcds.proto.CommData; 5 | 6 | public class Joystick extends CommData { 7 | public static final int SIZE=8; 8 | public static final int NUM_AXES=6; 9 | public static final int NUM_BUTTONS=12; 10 | // 6 axes of motion, each a signed byte/int8 11 | byte[] axes=new byte[] {0,0,0,0,0,0}; 12 | // 12 buttons max, stored in 16 bits with left 4 bits ignored 13 | boolean[] buttons=new boolean[] {false,false,false,false,false,false,false, 14 | false,false,false,false,false}; 15 | 16 | public byte getAxis(int index) { 17 | return axes[index]; 18 | } 19 | 20 | public void setAxis(int index,byte value) { 21 | axes[index]=value; 22 | } 23 | 24 | public int getNumAxes() { 25 | return axes.length; 26 | } 27 | 28 | public boolean getButton(int index) { 29 | return buttons[index]; 30 | } 31 | 32 | public void setButton(int index,boolean value) { 33 | buttons[index]=value; 34 | } 35 | 36 | public int getNumButtons() { 37 | return buttons.length; 38 | } 39 | 40 | @Override 41 | public byte[] serialize() { 42 | byte[] data=new byte[8]; 43 | for(int i=0;i>4); 51 | data[7]=(byte)bitsToInts(buttons2)[0]; 52 | return data; 53 | } 54 | 55 | @Override 56 | public void deserialize(byte[] data) { 57 | for(int i=0;i<6;i++) { 58 | axes[i]=data[i]; 59 | } 60 | boolean[] buttonBits=intsToBits(new int[] {(int)data[6],(int)data[7]}); 61 | buttonBits=Arrays.copyOfRange(buttonBits,4,16); 62 | reverseBits(buttonBits); 63 | this.buttons=buttonBits; 64 | } 65 | 66 | @Override 67 | public int hashCode() { 68 | final int prime=31; 69 | int result=1; 70 | result=prime*result+Arrays.hashCode(axes); 71 | result=prime*result+Arrays.hashCode(buttons); 72 | return result; 73 | } 74 | 75 | @Override 76 | public boolean equals(Object obj) { 77 | if(this==obj) { 78 | return true; 79 | } 80 | if(obj==null) { 81 | return false; 82 | } 83 | if(getClass()!=obj.getClass()) { 84 | return false; 85 | } 86 | Joystick other=(Joystick)obj; 87 | if(!Arrays.equals(axes,other.axes)) { 88 | return false; 89 | } 90 | if(!Arrays.equals(buttons,other.buttons)) { 91 | return false; 92 | } 93 | return true; 94 | } 95 | 96 | private static boolean[] reverseBits(boolean[] bits) { 97 | for(int i=0;i 3 | 4.0.0 4 | 5 | FRCDS 6 | parent 7 | 0.2 8 | 9 | DriverStation-PC 10 | 0.3 11 | FRC DriverStation PC 12 | A driver station program for PC, written in Java, that uses the FRCDS communication library 13 | 14 | ${project.basedir}/targets/natives/ 15 | natives/ 16 | 17 | 18 | 19 | 20 | maven-compiler-plugin 21 | 3.1 22 | 23 | 1.7 24 | 1.7 25 | 26 | 27 | 28 | com.googlecode.mavennatives 29 | maven-nativedependencies-plugin 30 | 0.0.7 31 | 32 | 33 | unpacknatives 34 | generate-resources 35 | 36 | copy 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-shade-plugin 44 | 1.6 45 | 46 | 47 | package 48 | 49 | shade 50 | 51 | 52 | 53 | 55 | org.anidev.frcds.pc.DriverStationMain 56 | 57 | 58 | 59 | 60 | *:* 61 | 62 | META-INF/*.SF 63 | META-INF/*.DSA 64 | META-INF/*.RSA 65 | 66 | 67 | 68 | ${project.bindir}/driverstation-pc.jar 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | FRCDS 78 | DriverStation-Common 79 | 0.3 80 | 81 | 82 | FRCDS 83 | Netconsole-PC 84 | 0.2 85 | 86 | 87 | FRCDS 88 | Java-Comm 89 | 1.0 90 | 91 | 92 | FRCDS 93 | Utils 94 | 2.0 95 | 96 | 97 | FRCDS-Libs 98 | forms 99 | 1.3.0 100 | 101 | 102 | net.java.dev.jna 103 | jna 104 | 4.0.0 105 | 106 | 107 | net.java.jinput 108 | jinput 109 | 2.0.5 110 | 111 | 112 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/gui/EnhancedToggleButton.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.gui; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Graphics; 6 | import java.awt.Graphics2D; 7 | import java.awt.Paint; 8 | import java.awt.Rectangle; 9 | import java.awt.event.ItemEvent; 10 | import java.awt.event.ItemListener; 11 | import javax.swing.JToggleButton; 12 | import org.anidev.utils.Utils; 13 | 14 | /** 15 | * JToggleButton used for enable and disable 16 | */ 17 | class EnhancedToggleButton extends JToggleButton implements 18 | ItemListener { 19 | private Color origColor; 20 | private Color selectedColor; 21 | private EnhancedToggleButton.BorderCollapse borderCollapse; 22 | private Paint borderColor=null; 23 | private static final int BORDER_SIZE=4; 24 | private static final int BORDER_PADDING=2; 25 | private static final int BORDER_TRANSLATE=BORDER_SIZE+BORDER_PADDING; 26 | 27 | /** 28 | * Set the appearence of the button 29 | * @param text the String displayed on the button 30 | * @param overlayColor the color of the overlay 31 | * @param selectedAlpha the alpha value 32 | * @param border BorderCollapse so the border can be put in the right place 33 | */ 34 | public EnhancedToggleButton(String text,Color overlayColor, 35 | double selectedAlpha,EnhancedToggleButton.BorderCollapse border) { 36 | super(text); 37 | this.borderCollapse=border; 38 | this.origColor=getBackground(); 39 | selectedColor=Utils.calcAlpha(selectedAlpha,overlayColor,origColor); 40 | setFont(new Font("Arial",Font.BOLD,12)); 41 | addItemListener(this); 42 | changeState(isSelected()); 43 | Object borderPref=Utils.getNimbusPref("nimbusBorder",this); 44 | if(borderPref!=null&&borderPref instanceof Paint) { 45 | borderColor=(Paint)borderPref; 46 | } 47 | } 48 | 49 | /* (non-Javadoc) 50 | * @see javax.swing.AbstractButton#setSelected(boolean) 51 | */ 52 | public void setSelected(boolean selected) { 53 | super.setSelected(selected); 54 | changeState(selected); 55 | } 56 | 57 | /** 58 | * Changes the background and foreground colors 59 | * @param selected whether or not the button is selected 60 | */ 61 | public void changeState(boolean selected) { 62 | if(selected) { 63 | setBackground(selectedColor); 64 | setForeground(null); 65 | } else { 66 | setBackground(null); 67 | setForeground(selectedColor); 68 | } 69 | } 70 | 71 | /* (non-Javadoc) 72 | * @see javax.swing.JComponent#paintComponent(java.awt.Graphics) 73 | */ 74 | @Override 75 | public void paintComponent(Graphics g) { 76 | Rectangle bounds=g.getClipBounds(); 77 | switch(borderCollapse) { 78 | case BOTTOM: 79 | g.translate(0,BORDER_TRANSLATE); 80 | break; 81 | case TOP: 82 | g.translate(0,-BORDER_TRANSLATE); 83 | break; 84 | default: 85 | } 86 | super.paintComponent(g); 87 | g.setClip(bounds); 88 | if(borderColor!=null&&g instanceof Graphics2D) { 89 | Graphics2D g2d=(Graphics2D)g; 90 | g2d.setPaint(borderColor); 91 | int minX=bounds.x+BORDER_SIZE; 92 | int maxX=bounds.x+bounds.width-BORDER_SIZE; 93 | int minY=bounds.y+BORDER_SIZE; 94 | int maxY=bounds.y+bounds.height-BORDER_SIZE; 95 | switch(borderCollapse) { 96 | case BOTTOM: 97 | g.drawLine(minX,maxY-BORDER_PADDING,maxX,maxY 98 | -BORDER_PADDING); 99 | break; 100 | case TOP: 101 | g.drawLine(minX,minY+BORDER_PADDING,maxX,minY 102 | +BORDER_PADDING); 103 | break; 104 | case NONE: 105 | } 106 | } 107 | } 108 | 109 | /* (non-Javadoc) 110 | * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent) 111 | */ 112 | @Override 113 | public void itemStateChanged(ItemEvent e) { 114 | if(!(e.getSource() instanceof EnhancedToggleButton)) { 115 | return; 116 | } 117 | EnhancedToggleButton button=(EnhancedToggleButton)e.getSource(); 118 | button.changeState(e.getStateChange()==ItemEvent.SELECTED); 119 | } 120 | 121 | /** 122 | * Where to have a border 123 | */ 124 | public static enum BorderCollapse { 125 | NONE, 126 | BOTTOM, 127 | TOP; 128 | } 129 | } -------------------------------------------------------------------------------- /java/Utils/src/main/java/org/anidev/utils/GTKIconTheme.java: -------------------------------------------------------------------------------- 1 | package org.anidev.utils; 2 | 3 | import java.awt.Image; 4 | import java.io.File; 5 | import java.io.IOException; 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | import java.net.URI; 9 | import java.util.HashMap; 10 | import javax.imageio.ImageIO; 11 | import javax.swing.Icon; 12 | import javax.swing.ImageIcon; 13 | import com.kitfox.svg.app.beans.SVGIcon; 14 | import com.sun.jna.Native; 15 | import com.sun.jna.Pointer; 16 | 17 | public class GTKIconTheme { 18 | private static final int GTK_ICON_LOOKUP_GENERIC_FALLBACK=1<<3; 19 | private static final HashMap ICON_MAP=new HashMap<>(); 20 | private static Pointer theme=null; 21 | private static boolean initFailed=false; 22 | static { 23 | addIcon("arrow-up",",go-up",16); 24 | addIcon("arrow-down",",go-down",16); 25 | addIcon("delete","edit-delete",22); 26 | addIcon("pause","media-playback-pause",22); 27 | addIcon("list","view-list-details",22); 28 | addIcon("text","utilities-terminal",22); 29 | addIcon("status-bad","dialog-cancel",16); 30 | addIcon("status-good","dialog-ok",16); 31 | init(); 32 | } 33 | 34 | private static void addIcon(String name,String id,int size) { 35 | if(id.equals("")) { 36 | id=name; 37 | } else if(id.startsWith(",")) { 38 | id=name+id; 39 | } 40 | IconInfo info=new IconInfo(id,size); 41 | ICON_MAP.put(name,info); 42 | } 43 | 44 | public static Icon findIcon(String name) { 45 | if(name==null||"".equals(name)) { 46 | return null; 47 | } 48 | int dotIndex=name.lastIndexOf('.'); 49 | if(dotIndex>-1) { 50 | name=name.substring(0,dotIndex); 51 | } 52 | IconInfo info=ICON_MAP.get(name); 53 | if(info==null) { 54 | return null; 55 | } 56 | return info.cachedIcon; 57 | } 58 | 59 | private static Icon loadIcon(IconInfo info) { 60 | String[] ids=info.id.split(","); 61 | for(String id:ids) { 62 | Pointer infoPtr=gtk_icon_theme_lookup_icon(theme,id,info.size, 63 | GTK_ICON_LOOKUP_GENERIC_FALLBACK); 64 | if(infoPtr==null) { 65 | continue; 66 | } 67 | String filename=gtk_icon_info_get_filename(infoPtr); 68 | try { 69 | Icon icon=null; 70 | if(filename.toLowerCase().endsWith(".svg")) { 71 | icon=loadSVG(filename); 72 | } else { 73 | Image image=ImageIO.read(new File(filename)); 74 | icon=new ImageIcon(image); 75 | } 76 | if(icon==null) { 77 | continue; 78 | } 79 | return icon; 80 | } catch(IOException e) { 81 | continue; 82 | } 83 | } 84 | System.out.println("Did not find "+info.id); 85 | return null; 86 | } 87 | 88 | private static void init() { 89 | if(initFailed) { 90 | return; 91 | } 92 | if(theme!=null) { 93 | return; 94 | } 95 | try { 96 | Class XToolkit=Class.forName("sun.awt.X11.XToolkit"); 97 | Object toolkit=XToolkit.newInstance(); 98 | Method loadGTK=XToolkit.getMethod("loadGTK"); 99 | loadGTK.invoke(toolkit); 100 | try { 101 | Native.register("gtk-x11-2.0"); 102 | } catch(UnsatisfiedLinkError e) { 103 | initFailed=true; 104 | return; 105 | } 106 | theme=gtk_icon_theme_get_default(); 107 | for(IconInfo info:ICON_MAP.values()) { 108 | info.cachedIcon=loadIcon(info); 109 | } 110 | Method unloadGTK=XToolkit.getMethod("unload_gtk"); 111 | unloadGTK.invoke(toolkit); 112 | } catch(ClassNotFoundException|InstantiationException 113 | |IllegalAccessException|NoSuchMethodException|SecurityException 114 | |IllegalArgumentException|InvocationTargetException e1) { 115 | initFailed=true; 116 | return; 117 | } 118 | } 119 | 120 | private static SVGIcon loadSVG(String filename) { 121 | URI uri=new File(filename).toURI(); 122 | SVGIcon icon=new SVGIcon(); 123 | icon.setAntiAlias(true); 124 | icon.setSvgURI(uri); 125 | return icon; 126 | } 127 | 128 | private static native Pointer gtk_icon_theme_get_default(); 129 | 130 | private static native Pointer gtk_icon_theme_lookup_icon(Pointer theme, 131 | String id,int size,int flags); 132 | 133 | private static native String gtk_icon_info_get_filename(Pointer iconInfo); 134 | 135 | private static class IconInfo { 136 | public String id; 137 | public int size; 138 | public Icon cachedIcon=null; 139 | 140 | public IconInfo(String id,int size) { 141 | this.id=id; 142 | this.size=size; 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/ControlFlags.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto; 2 | 3 | import org.anidev.frcds.proto.torobot.OperationMode; 4 | 5 | public class ControlFlags extends CommData { 6 | public static final int SIZE=1; 7 | private boolean reset=false; 8 | private boolean notEStop=true; 9 | private boolean enabled=false; 10 | private boolean autonomous=false; 11 | private boolean fmsAttached=false; 12 | private boolean resync=false; 13 | private boolean test=false; 14 | private boolean checkVersions=false; 15 | 16 | public boolean isReset() { 17 | return reset; 18 | } 19 | 20 | public void setReset(boolean reset) { 21 | this.reset=reset; 22 | } 23 | 24 | public boolean isNotEStop() { 25 | return notEStop; 26 | } 27 | 28 | public void setNotEStop(boolean notEStop) { 29 | this.notEStop=notEStop; 30 | } 31 | 32 | public boolean isEnabled() { 33 | return enabled; 34 | } 35 | 36 | public void setEnabled(boolean enabled) { 37 | this.enabled=enabled; 38 | } 39 | 40 | public boolean isAutonomous() { 41 | return autonomous; 42 | } 43 | 44 | public void setAutonomous(boolean autonomous) { 45 | this.autonomous=autonomous; 46 | if(autonomous) { 47 | this.test=false; 48 | } 49 | } 50 | 51 | public boolean isFmsAttached() { 52 | return fmsAttached; 53 | } 54 | 55 | public void setFmsAttached(boolean fmsAttached) { 56 | this.fmsAttached=fmsAttached; 57 | } 58 | 59 | public boolean isResync() { 60 | return resync; 61 | } 62 | 63 | public void setResync(boolean resync) { 64 | this.resync=resync; 65 | } 66 | 67 | public boolean isTest() { 68 | return test; 69 | } 70 | 71 | public void setTest(boolean test) { 72 | this.test=test; 73 | if(test) { 74 | this.autonomous=false; 75 | } 76 | } 77 | 78 | public boolean isCheckVersions() { 79 | return checkVersions; 80 | } 81 | 82 | public void setCheckVersions(boolean checkVersions) { 83 | this.checkVersions=checkVersions; 84 | } 85 | 86 | public OperationMode getOperationMode() { 87 | if(autonomous) { 88 | return OperationMode.AUTONOMOUS; 89 | } else if(test) { 90 | return OperationMode.TEST; 91 | } else { 92 | return OperationMode.TELEOPERATED; 93 | } 94 | } 95 | 96 | public void setOperationMode(OperationMode mode) { 97 | autonomous=OperationMode.AUTONOMOUS.equals(mode); 98 | test=OperationMode.TEST.equals(mode); 99 | } 100 | 101 | @Override 102 | public byte[] serialize() { 103 | return serialize(DataDir.TOROBOT); 104 | } 105 | 106 | public byte[] serialize(DataDir dir) { 107 | int data=-1; 108 | if(dir==DataDir.TOROBOT) { 109 | data=bitsToInts(new boolean[] {reset,notEStop,enabled, 110 | autonomous,fmsAttached,resync,test,checkVersions})[0]; 111 | } else { 112 | data=bitsToInts(new boolean[] {checkVersions,test,resync, 113 | fmsAttached,autonomous,enabled,notEStop,reset})[0]; 114 | } 115 | return new byte[] {(byte)data}; 116 | } 117 | 118 | @Override 119 | public void deserialize(byte[] data) { 120 | deserialize(data,DataDir.TOROBOT); 121 | } 122 | 123 | public void deserialize(byte[] data,DataDir dir) { 124 | boolean[] flags=intsToBits(new int[] {data[0]&0xFF}); 125 | if(dir==DataDir.TOROBOT) { 126 | reset=flags[0]; 127 | notEStop=flags[1]; 128 | enabled=flags[2]; 129 | autonomous=flags[3]; 130 | fmsAttached=flags[4]; 131 | resync=flags[5]; 132 | test=flags[6]; 133 | checkVersions=flags[7]; 134 | } else { 135 | // TODO Figure out if this is accurate... 136 | // If it is, then its just the opposite of above 137 | checkVersions=flags[0]; 138 | test=flags[1]; 139 | resync=flags[2]; 140 | fmsAttached=flags[3]; 141 | autonomous=flags[4]; 142 | enabled=flags[5]; 143 | notEStop=flags[6]; 144 | reset=flags[7]; 145 | } 146 | } 147 | 148 | @Override 149 | public int hashCode() { 150 | final int prime=31; 151 | int result=1; 152 | result=prime*result+(autonomous?1231:1237); 153 | result=prime*result+(checkVersions?1231:1237); 154 | result=prime*result+(enabled?1231:1237); 155 | result=prime*result+(fmsAttached?1231:1237); 156 | result=prime*result+(notEStop?1231:1237); 157 | result=prime*result+(reset?1231:1237); 158 | result=prime*result+(resync?1231:1237); 159 | result=prime*result+(test?1231:1237); 160 | return result; 161 | } 162 | 163 | @Override 164 | public boolean equals(Object obj) { 165 | if(this==obj) { 166 | return true; 167 | } 168 | if(obj==null) { 169 | return false; 170 | } 171 | if(getClass()!=obj.getClass()) { 172 | return false; 173 | } 174 | ControlFlags other=(ControlFlags)obj; 175 | if(autonomous!=other.autonomous) { 176 | return false; 177 | } 178 | if(checkVersions!=other.checkVersions) { 179 | return false; 180 | } 181 | if(enabled!=other.enabled) { 182 | return false; 183 | } 184 | if(fmsAttached!=other.fmsAttached) { 185 | return false; 186 | } 187 | if(notEStop!=other.notEStop) { 188 | return false; 189 | } 190 | if(reset!=other.reset) { 191 | return false; 192 | } 193 | if(resync!=other.resync) { 194 | return false; 195 | } 196 | if(test!=other.test) { 197 | return false; 198 | } 199 | return true; 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /java/Utils/src/main/java/org/anidev/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package org.anidev.utils; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Image; 6 | import java.io.File; 7 | import java.io.FileNotFoundException; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.io.OutputStream; 12 | import java.net.URL; 13 | import java.text.NumberFormat; 14 | import java.util.Enumeration; 15 | import java.util.prefs.Preferences; 16 | import javax.imageio.ImageIO; 17 | import javax.swing.AbstractButton; 18 | import javax.swing.ButtonGroup; 19 | import javax.swing.Icon; 20 | import javax.swing.ImageIcon; 21 | import javax.swing.JComponent; 22 | import javax.swing.UIDefaults; 23 | import javax.swing.UIManager; 24 | 25 | public class Utils { 26 | public static final String TMPDIR; 27 | static { 28 | String separator=System.getProperty("file.separator"); 29 | StringBuilder tmpPathBuilder=new StringBuilder(); 30 | tmpPathBuilder.append(System.getProperty("java.io.tmpdir")); 31 | tmpPathBuilder.append(separator); 32 | tmpPathBuilder.append("FRCDS-files"); 33 | tmpPathBuilder.append(separator); 34 | TMPDIR=tmpPathBuilder.toString(); 35 | } 36 | 37 | public static int calcAlpha(double alpha,int newColor,int oldColor) { 38 | return (int)Math.round(alpha*newColor+(1-alpha)*oldColor); 39 | } 40 | 41 | public static Color calcAlpha(double alpha,Color newColor,Color oldColor) { 42 | int calcR=calcAlpha(alpha,newColor.getRed(),oldColor.getRed()); 43 | int calcG=calcAlpha(alpha,newColor.getGreen(),oldColor.getGreen()); 44 | int calcB=calcAlpha(alpha,newColor.getBlue(),oldColor.getBlue()); 45 | return new Color(calcR,calcG,calcB); 46 | } 47 | 48 | public static AbstractButton getSelectedButton(ButtonGroup group) { 49 | Enumeration buttons=group.getElements(); 50 | while(buttons.hasMoreElements()) { 51 | AbstractButton button=buttons.nextElement(); 52 | if(button.isSelected()) { 53 | return button; 54 | } 55 | } 56 | return null; 57 | } 58 | 59 | public static Icon getIcon(String name) { 60 | Icon icon=GTKIconTheme.findIcon(name); 61 | if(icon!=null) { 62 | return icon; 63 | } 64 | try { 65 | URL imageUrl=Utils.class.getResource("/"+name); 66 | if(imageUrl==null) { 67 | return null; 68 | } 69 | Image image=ImageIO.read(imageUrl); 70 | icon=new ImageIcon(image); 71 | return icon; 72 | } catch(IOException e) { 73 | e.printStackTrace(); 74 | return null; 75 | } 76 | } 77 | 78 | public static Preferences getPrefs(Class cls) { 79 | return Preferences.userNodeForPackage(cls); 80 | } 81 | 82 | public static Object getNimbusPref(String key,JComponent c) { 83 | UIDefaults uiValues=UIManager.getLookAndFeelDefaults(); 84 | Object overrides=c.getClientProperty("Nimbus.Overrides"); 85 | Object pref=null; 86 | if(overrides!=null&&overrides instanceof UIDefaults) { 87 | pref=((UIDefaults)overrides).get(key); 88 | } 89 | if(pref==null) { 90 | pref=uiValues.get(key); 91 | } 92 | return pref; 93 | } 94 | 95 | public static void setLookAndFeel() { 96 | String lafStr=System.getProperty("anidev.pcds.laf",""); 97 | switch(lafStr) { 98 | case "": 99 | lafStr="com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"; 100 | break; 101 | case "": 102 | lafStr=UIManager.getSystemLookAndFeelClassName(); 103 | break; 104 | case "": 105 | lafStr=UIManager.getCrossPlatformLookAndFeelClassName(); 106 | break; 107 | } 108 | try { 109 | UIManager.setLookAndFeel(lafStr); 110 | } catch(Exception e) { 111 | System.err.println("Error while setting "+lafStr+" L&F."); 112 | e.printStackTrace(); 113 | } 114 | } 115 | 116 | public static Font makeMonoFont(Font oldFont) { 117 | return new Font(Font.MONOSPACED,oldFont.getStyle(),oldFont.getSize()); 118 | } 119 | 120 | public static File extractJarResource(String fileName) throws IOException { 121 | File file=new File(TMPDIR+fileName); 122 | file.getParentFile().mkdirs(); 123 | if(file.exists()) { 124 | return file; 125 | } 126 | InputStream fileStream=Utils.class.getResourceAsStream("/"+fileName); 127 | System.out.println(fileName); 128 | if(fileStream==null) { 129 | return null; 130 | } 131 | OutputStream outStream=null; 132 | try { 133 | outStream=new FileOutputStream(file); 134 | } catch(FileNotFoundException e) { 135 | e.printStackTrace(); 136 | fileStream.close(); 137 | return null; 138 | } 139 | System.out.println("Extracting "+fileName+"..."); 140 | int c=0; 141 | byte[] buf=new byte[256]; 142 | try { 143 | while(true) { 144 | c=fileStream.read(buf); 145 | outStream.write(buf); 146 | if(c
No Robot Communication
"); 86 | operationStatusLabel.setFont(new Font("Arial",Font.BOLD,18)); 87 | operationStatusLabel.setHorizontalAlignment(SwingConstants.CENTER); 88 | operationStatusLabel.setAlignmentX(Component.CENTER_ALIGNMENT); 89 | operationStatusPanel.add(operationStatusLabel,BorderLayout.CENTER); 90 | } 91 | 92 | /** 93 | * Set the voltage text 94 | * @param volts the battery voltage 95 | */ 96 | public void setBatteryVolts(double volts) { 97 | if(volts<0) { 98 | voltsValueLabel.setText("--.--"); 99 | } else { 100 | voltsValueLabel.setText(voltsFormat.format(volts)); 101 | } 102 | } 103 | 104 | /** 105 | * @param on whether or not communication is on 106 | */ 107 | public void setCommunicationState(boolean on) { 108 | // communicationStatus.setOn(on); 109 | } 110 | } 111 | 112 | /** 113 | * good/bad status indicator 114 | */ 115 | class StatusIndicator extends JPanel { 116 | private JLabel icon; 117 | private JLabel label; 118 | private boolean on; 119 | private static final Icon goodIcon; 120 | private static final Icon badIcon; 121 | static { 122 | goodIcon=Utils.getIcon("status-good.png"); 123 | badIcon=Utils.getIcon("status-bad.png"); 124 | } 125 | 126 | /** 127 | * Set the layout and add contents 128 | * @param text text for the label 129 | */ 130 | public StatusIndicator(String text) { 131 | setLayout(new FormLayout(new ColumnSpec[] {ColumnSpec.decode("10px"), 132 | ColumnSpec.decode("16px"),ColumnSpec.decode("4px"), 133 | ColumnSpec.decode("default:grow"),},new RowSpec[] {RowSpec 134 | .decode("default:grow"),})); 135 | icon=new JLabel(""); 136 | icon.setPreferredSize(new Dimension(16,16)); 137 | add(icon,"2, 1, left, fill"); 138 | label=new JLabel(text); 139 | add(label,"4, 1, fill, fill"); 140 | setOn(false); 141 | } 142 | 143 | /** 144 | * @return text of the label 145 | */ 146 | public String getText() { 147 | return label.getText(); 148 | } 149 | 150 | /** 151 | * @param text text of the label 152 | */ 153 | public void setText(String text) { 154 | label.setText(text); 155 | } 156 | 157 | /** 158 | * @return true if it is good false otherwise 159 | */ 160 | public boolean isOn() { 161 | return on; 162 | } 163 | 164 | /** 165 | * Set on and the icon 166 | * @param newOn true if goodIcon should be shown false for badIcon 167 | */ 168 | public void setOn(boolean newOn) { 169 | on=newOn; 170 | icon.setIcon((on?goodIcon:badIcon)); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-Common/src/main/java/org/anidev/frcds/common/DriverStation.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.common; 2 | 3 | import org.anidev.frcds.common.types.BatteryProvider; 4 | import org.anidev.frcds.proto.CommData; 5 | import org.anidev.frcds.proto.ControlFlags; 6 | import org.anidev.frcds.proto.FRCCommunication; 7 | import org.anidev.frcds.proto.FRCCommunicationListener; 8 | import org.anidev.frcds.proto.tods.FRCRobotControl; 9 | import org.anidev.frcds.proto.torobot.FRCCommonControl; 10 | import org.anidev.frcds.proto.torobot.OperationMode; 11 | 12 | public abstract class DriverStation { 13 | public static final double UPDATE_HERTZ=50.0; 14 | public static final double SLOW_HERTZ=1.0; 15 | private FRCCommunication frcComm=new FRCCommunication(); 16 | private FRCCommonControl dsControl=new FRCCommonControl(); 17 | private FRCRobotControl lastRobotControl=null; 18 | private BatteryProvider batteryProvider=null; 19 | private Thread enabledLoop=null; 20 | private Thread commonLoop=null; 21 | private OperationMode mode=OperationMode.TELEOPERATED; 22 | private boolean enabled=false; 23 | private double elapsedTime=0.0; 24 | private double batteryPercent=-1.0; 25 | private int teamID=0; 26 | 27 | protected DriverStation() { 28 | frcComm.addRobotDataListener(new FRCCommunicationListener() { 29 | @Override 30 | public void receivedData(CommData data) { 31 | if(!(data instanceof FRCRobotControl)) { 32 | return; 33 | } 34 | FRCRobotControl robotControl=(FRCRobotControl)data; 35 | setLastRobotControl(robotControl); 36 | } 37 | }); 38 | } 39 | 40 | public void setBatteryProvider(BatteryProvider batteryProvider) { 41 | this.batteryProvider=batteryProvider; 42 | } 43 | 44 | public BatteryProvider getBatteryProvider() { 45 | return batteryProvider; 46 | } 47 | 48 | public void sendControlData() { 49 | dsControl.setPacketIndex(dsControl.getPacketIndex()+1); 50 | frcComm.sendToRobot(dsControl); 51 | } 52 | 53 | public OperationMode getMode() { 54 | return mode; 55 | } 56 | 57 | public void setMode(OperationMode mode) { 58 | this.mode=mode; 59 | ControlFlags flags=dsControl.getControlFlags(); 60 | flags.setOperationMode(mode); 61 | dsControl.setControlFlags(flags); 62 | setModeImpl(); 63 | } 64 | 65 | public boolean isEnabled() { 66 | return enabled; 67 | } 68 | 69 | public void setEnabled(boolean enabled) { 70 | this.enabled=enabled; 71 | dsControl.getControlFlags().setEnabled(enabled); 72 | if(enabled) { 73 | if(enabledLoop!=null&&enabledLoop.isAlive()) { 74 | return; 75 | } 76 | enabledLoop=new Thread(new EnabledLoop(this,UPDATE_HERTZ), 77 | "FRCDS Enabled Loop"); 78 | enabledLoop.start(); 79 | } else { 80 | if(enabledLoop!=null) { 81 | enabledLoop.interrupt(); 82 | } 83 | enabledLoop=null; 84 | setElapsedTime(0.0); 85 | } 86 | } 87 | 88 | public double getElapsedTime() { 89 | return elapsedTime; 90 | } 91 | 92 | public void setElapsedTime(double elapsedTime) { 93 | this.elapsedTime=elapsedTime; 94 | setElapsedTimeImpl(); 95 | } 96 | 97 | public int getTeamID() { 98 | return teamID; 99 | } 100 | 101 | public void setTeamID(int teamID) { 102 | this.teamID=teamID%10000; 103 | dsControl.setTeamID(teamID); 104 | frcComm.setTeamID(teamID); 105 | setTeamIDImpl(); 106 | } 107 | 108 | public void refreshBattery() { 109 | if(batteryProvider==null) { 110 | batteryPercent=-1.0; 111 | } else { 112 | batteryPercent=batteryProvider.getBatteryPercent(); 113 | } 114 | setBatteryPercentImpl(); 115 | } 116 | 117 | public void setLastRobotControl(FRCRobotControl control) { 118 | this.lastRobotControl=control; 119 | setLastRobotControlImpl(); 120 | } 121 | 122 | public FRCRobotControl getLastRobotControl() { 123 | return lastRobotControl; 124 | } 125 | 126 | protected void startLoops() { 127 | commonLoop=new Thread(new CommonLoop(this,SLOW_HERTZ), 128 | "FRCDS Common Loop"); 129 | commonLoop.start(); 130 | } 131 | 132 | protected void setEnabledImpl() { 133 | } 134 | 135 | protected void setElapsedTimeImpl() { 136 | } 137 | 138 | protected void setTeamIDImpl() { 139 | } 140 | 141 | protected void setBatteryPercentImpl() { 142 | } 143 | 144 | protected void setModeImpl() { 145 | } 146 | 147 | protected void setLastRobotControlImpl() { 148 | } 149 | 150 | protected void doCommonLoopImpl() { 151 | } 152 | 153 | protected void doEnabledLoopImpl() { 154 | } 155 | 156 | /** 157 | * @return the batteryPercent 158 | */ 159 | protected double getBatteryPercent() { 160 | return batteryPercent; 161 | } 162 | 163 | /** 164 | * @param batteryPercent 165 | * the batteryPercent to set 166 | */ 167 | protected void setBatteryPercent(double batteryPercent) { 168 | this.batteryPercent=batteryPercent; 169 | } 170 | 171 | /** 172 | * @return the frcComm 173 | */ 174 | protected FRCCommunication getFrcComm() { 175 | return frcComm; 176 | } 177 | 178 | /** 179 | * @param frcComm 180 | * the frcComm to set 181 | */ 182 | protected void setFrcComm(FRCCommunication frcComm) { 183 | this.frcComm=frcComm; 184 | } 185 | 186 | /** 187 | * @return the dsControl 188 | */ 189 | protected FRCCommonControl getDsControl() { 190 | return dsControl; 191 | } 192 | 193 | /** 194 | * @param dsControl 195 | * the dsControl to set 196 | */ 197 | protected void setDsControl(FRCCommonControl dsControl) { 198 | this.dsControl=dsControl; 199 | } 200 | 201 | /** 202 | * @return the enabledLoop 203 | */ 204 | protected Thread getEnabledLoop() { 205 | return enabledLoop; 206 | } 207 | 208 | /** 209 | * @param enabledLoop 210 | * the enabledLoop to set 211 | */ 212 | protected void setEnabledLoop(Thread enabledLoop) { 213 | this.enabledLoop=enabledLoop; 214 | } 215 | 216 | /** 217 | * @return the commonLoop 218 | */ 219 | protected Thread getCommonLoop() { 220 | return commonLoop; 221 | } 222 | 223 | /** 224 | * @param commonLoop 225 | * the commonLoop to set 226 | */ 227 | protected void setCommonLoop(Thread commonLoop) { 228 | this.commonLoop=commonLoop; 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore 3 | org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull 4 | org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault 5 | org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable 6 | org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled 7 | org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning 8 | org.eclipse.jdt.core.compiler.problem.autoboxing=ignore 9 | org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning 10 | org.eclipse.jdt.core.compiler.problem.deadCode=warning 11 | org.eclipse.jdt.core.compiler.problem.deprecation=warning 12 | org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled 13 | org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled 14 | org.eclipse.jdt.core.compiler.problem.discouragedReference=warning 15 | org.eclipse.jdt.core.compiler.problem.emptyStatement=warning 16 | org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore 17 | org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore 18 | org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled 19 | org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore 20 | org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning 21 | org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning 22 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=error 23 | org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning 24 | org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled 25 | org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning 26 | org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning 27 | org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore 28 | org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore 29 | org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning 30 | org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore 31 | org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore 32 | org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled 33 | org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore 34 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore 35 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled 36 | org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore 37 | org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore 38 | org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning 39 | org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning 40 | org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore 41 | org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error 42 | org.eclipse.jdt.core.compiler.problem.nullReference=warning 43 | org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error 44 | org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning 45 | org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning 46 | org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore 47 | org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning 48 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore 49 | org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning 50 | org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning 51 | org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning 52 | org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore 53 | org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore 54 | org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore 55 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore 56 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=warning 57 | org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled 58 | org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning 59 | org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled 60 | org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled 61 | org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore 62 | org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning 63 | org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled 64 | org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning 65 | org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning 66 | org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore 67 | org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning 68 | org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore 69 | org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore 70 | org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore 71 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore 72 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled 73 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled 74 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled 75 | org.eclipse.jdt.core.compiler.problem.unusedImport=warning 76 | org.eclipse.jdt.core.compiler.problem.unusedLabel=warning 77 | org.eclipse.jdt.core.compiler.problem.unusedLocal=warning 78 | org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning 79 | org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore 80 | org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled 81 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled 82 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled 83 | org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning 84 | org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning 85 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning 86 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/tods/FRCRobotControl.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.tods; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ShortBuffer; 6 | import java.util.Arrays; 7 | import org.anidev.frcds.proto.CommData; 8 | import org.anidev.frcds.proto.ControlFlags; 9 | import org.anidev.frcds.proto.DataDir; 10 | import org.anidev.frcds.proto.Version; 11 | 12 | public class FRCRobotControl extends CommData { 13 | public static final int SIZE=32; 14 | public static final Version CURRENT_VERSION=new Version("12191200"); 15 | private static int totalPackets=0; 16 | private ControlFlags control=new ControlFlags(); 17 | private int batteryVolts=-1; 18 | private int batteryMV=-1; 19 | private DigitalOutputs digitalOutputs=new DigitalOutputs(); 20 | private byte[] unknown1=new byte[] {0,0,0,0}; 21 | private int teamID=0; 22 | private MacAddress macAddress=new MacAddress(); 23 | private Version version=CURRENT_VERSION; 24 | private byte[] unknown2=new byte[] {0,0,0,0,0,0}; 25 | private int packetIndex=++totalPackets; 26 | 27 | public static int getTotalPackets() { 28 | return totalPackets; 29 | } 30 | 31 | public ControlFlags getControlFlags() { 32 | return control; 33 | } 34 | 35 | public void setControlFlags(ControlFlags control) { 36 | this.control=control; 37 | } 38 | 39 | public int getBatteryVoltsInt() { 40 | return batteryVolts; 41 | } 42 | 43 | public void setBatteryVoltsInt(int batteryVolts) { 44 | this.batteryVolts=batteryVolts; 45 | } 46 | 47 | public int getBatteryVoltsFraction() { 48 | return batteryMV; 49 | } 50 | 51 | public void setBatteryFraction(int batteryMV) { 52 | this.batteryMV=batteryMV; 53 | } 54 | 55 | public double getBatteryVolts() { 56 | if(batteryVolts<0||batteryMV<0) { 57 | return -1.0; 58 | } 59 | return batteryVolts+(batteryMV*1.0/1000.0); 60 | } 61 | 62 | public void setBatteryVolts(double volts) { 63 | if(volts<0) { 64 | this.batteryVolts=this.batteryMV=-1; 65 | } 66 | this.batteryVolts=(int)volts; 67 | this.batteryMV=(int)((volts-batteryVolts)*1000); 68 | } 69 | 70 | public DigitalOutputs getDigitalOutputs() { 71 | return digitalOutputs; 72 | } 73 | 74 | public void setDigitalOutputs(DigitalOutputs digitalOutputs) { 75 | this.digitalOutputs=digitalOutputs; 76 | } 77 | 78 | public int getTeamID() { 79 | return teamID; 80 | } 81 | 82 | public void setTeamID(int teamID) { 83 | this.teamID=teamID; 84 | } 85 | 86 | public MacAddress getMacAddress() { 87 | return macAddress; 88 | } 89 | 90 | public void setMacAddress(MacAddress macAddress) { 91 | this.macAddress=macAddress; 92 | } 93 | 94 | public Version getVersion() { 95 | return version; 96 | } 97 | 98 | public void setVersion(Version version) { 99 | this.version=version; 100 | } 101 | 102 | public int getPacketIndex() { 103 | return packetIndex; 104 | } 105 | 106 | public void setPacketIndex(int packetIndex) { 107 | this.packetIndex=packetIndex; 108 | } 109 | 110 | @Override 111 | public byte[] serialize() { 112 | ByteArrayOutputStream byteStream=new ByteArrayOutputStream(SIZE); 113 | byte[] controlBytes=control.serialize(DataDir.TODS); 114 | byteStream.write(controlBytes,0,controlBytes.length); 115 | byteStream.write(new byte[] {(byte)batteryVolts},0,1); 116 | byteStream.write(new byte[] {(byte)batteryMV},0,1); 117 | byte[] digitalOutputsBytes=digitalOutputs.serialize(); 118 | byteStream.write(digitalOutputsBytes,0,digitalOutputsBytes.length); 119 | byteStream.write(unknown1,0,unknown1.length); 120 | ByteBuffer byteBuffer=ByteBuffer.allocate(2); 121 | byteBuffer.order(BYTE_ORDER); 122 | byteBuffer.putShort((short)teamID); 123 | byte[] teamIDBytes=byteBuffer.array(); 124 | byteStream.write(teamIDBytes,0,teamIDBytes.length); 125 | byte[] macAddressBytes=macAddress.serialize(); 126 | byteStream.write(macAddressBytes,0,macAddressBytes.length); 127 | byte[] versionBytes=version.serialize(); 128 | byteStream.write(versionBytes,0,versionBytes.length); 129 | byteStream.write(unknown2,0,unknown2.length); 130 | byteBuffer.putShort(0,(short)packetIndex); 131 | byte[] packetIndexBytes=byteBuffer.array(); 132 | byteStream.write(packetIndexBytes,0,packetIndexBytes.length); 133 | return byteStream.toByteArray(); 134 | } 135 | 136 | @Override 137 | public void deserialize(byte[] data) { 138 | int index=0; 139 | control.deserialize(Arrays.copyOfRange(data,index, 140 | index+=ControlFlags.SIZE),DataDir.TODS); 141 | batteryVolts=data[index++]&0xFF; 142 | batteryMV=data[index++]&0xFF; 143 | digitalOutputs.deserialize(Arrays.copyOfRange(data,index, 144 | index+=DigitalOutputs.SIZE)); 145 | unknown1=Arrays.copyOfRange(data,index,index+=unknown1.length); 146 | ByteBuffer byteBuffer=ByteBuffer.allocate(2); 147 | byteBuffer.put(data[index++]).put(data[index++]); 148 | byteBuffer.position(0); 149 | ShortBuffer shortBuffer=byteBuffer.asShortBuffer(); 150 | teamID=shortBuffer.get(0); 151 | macAddress.deserialize(Arrays.copyOfRange(data,index,index+=MacAddress.SIZE)); 152 | version.deserialize(Arrays.copyOfRange(data,index,index+=Version.SIZE)); 153 | unknown2=Arrays.copyOfRange(data,index,index+=unknown2.length); 154 | byteBuffer.put(0,data[index++]).put(1,data[index++]); 155 | packetIndex=shortBuffer.get(0); 156 | } 157 | 158 | @Override 159 | public int hashCode() { 160 | final int prime=31; 161 | int result=1; 162 | result=prime*result+batteryMV; 163 | result=prime*result+batteryVolts; 164 | result=prime*result+((control==null)?0:control.hashCode()); 165 | result=prime*result 166 | +((digitalOutputs==null)?0:digitalOutputs.hashCode()); 167 | result=prime*result+((macAddress==null)?0:macAddress.hashCode()); 168 | result=prime*result+packetIndex; 169 | result=prime*result+teamID; 170 | result=prime*result+Arrays.hashCode(unknown1); 171 | result=prime*result+Arrays.hashCode(unknown2); 172 | return result; 173 | } 174 | 175 | @Override 176 | public boolean equals(Object obj) { 177 | if(this==obj) { 178 | return true; 179 | } 180 | if(obj==null) { 181 | return false; 182 | } 183 | if(getClass()!=obj.getClass()) { 184 | return false; 185 | } 186 | FRCRobotControl other=(FRCRobotControl)obj; 187 | if(batteryMV!=other.batteryMV) { 188 | return false; 189 | } 190 | if(batteryVolts!=other.batteryVolts) { 191 | return false; 192 | } 193 | if(control==null) { 194 | if(other.control!=null) { 195 | return false; 196 | } 197 | } else if(!control.equals(other.control)) { 198 | return false; 199 | } 200 | if(digitalOutputs==null) { 201 | if(other.digitalOutputs!=null) { 202 | return false; 203 | } 204 | } else if(!digitalOutputs.equals(other.digitalOutputs)) { 205 | return false; 206 | } 207 | if(macAddress==null) { 208 | if(other.macAddress!=null) { 209 | return false; 210 | } 211 | } else if(!macAddress.equals(other.macAddress)) { 212 | return false; 213 | } 214 | if(packetIndex!=other.packetIndex) { 215 | return false; 216 | } 217 | if(teamID!=other.teamID) { 218 | return false; 219 | } 220 | if(!Arrays.equals(unknown1,other.unknown1)) { 221 | return false; 222 | } 223 | if(!Arrays.equals(unknown2,other.unknown2)) { 224 | return false; 225 | } 226 | return true; 227 | } 228 | 229 | } 230 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/nc/Netconsole.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.nc; 2 | 3 | import java.io.IOException; 4 | import java.net.DatagramPacket; 5 | import java.net.DatagramSocket; 6 | import java.net.InetAddress; 7 | import java.net.SocketException; 8 | import java.net.UnknownHostException; 9 | import java.util.ArrayList; 10 | import java.util.Collections; 11 | import java.util.List; 12 | import java.util.concurrent.BlockingQueue; 13 | import java.util.concurrent.LinkedBlockingQueue; 14 | import java.util.concurrent.TimeUnit; 15 | import org.anidev.frcds.proto.DataDir; 16 | import org.anidev.utils.Utils; 17 | 18 | public class Netconsole { 19 | public static final int RECV_PORT=6666; 20 | public static final int SEND_PORT=6668; 21 | private volatile int teamID; 22 | private volatile InetAddress broadcastAddress=null; 23 | private volatile boolean paused=false; 24 | private volatile boolean closed=false; 25 | private int queueTimeout=40; 26 | private List listeners=Collections 27 | .synchronizedList(new ArrayList()); 28 | private List netconsoleMessages=Collections 29 | .synchronizedList(new ArrayList()); 30 | private DatagramSocket sendDataSocket; 31 | private DatagramSocket receiveDataSocket; 32 | private Thread sendDataThread; 33 | private Thread receiveDataThread; 34 | private BlockingQueue sendDataQueue; 35 | 36 | public Netconsole() { 37 | sendDataQueue=new LinkedBlockingQueue(); 38 | 39 | initSockets(); 40 | initThreads(); 41 | } 42 | 43 | public List getNetconsoleMessages() { 44 | return netconsoleMessages; 45 | } 46 | 47 | public NetconsoleMessage getNetconsoleMessage(int index) { 48 | return netconsoleMessages.get(index); 49 | } 50 | 51 | public void clearMessages() { 52 | netconsoleMessages.clear(); 53 | synchronized(listeners) { 54 | for(NetconsoleListener listener:listeners) { 55 | listener.messagesCleared(); 56 | } 57 | } 58 | } 59 | 60 | public void sendData(String data) { 61 | checkClosed(); 62 | try { 63 | sendDataQueue.offer(data,queueTimeout,TimeUnit.MILLISECONDS); 64 | } catch(InterruptedException e) { 65 | Thread.currentThread().interrupt(); 66 | } 67 | } 68 | 69 | public boolean isPaused() { 70 | return paused; 71 | } 72 | 73 | public void setPaused(boolean paused) { 74 | this.paused=paused; 75 | synchronized(listeners) { 76 | for(NetconsoleListener listener:listeners) { 77 | listener.pauseChanged(paused); 78 | } 79 | } 80 | } 81 | 82 | public int getTeamID() { 83 | return teamID; 84 | } 85 | 86 | public void setTeamID(int teamID) { 87 | if(teamID<=0) { 88 | broadcastAddress=null; 89 | return; 90 | } 91 | byte[] addrBytes=Utils.teamIDToAddress(teamID); 92 | addrBytes[3]=(byte)255; 93 | try { 94 | broadcastAddress=InetAddress.getByAddress(addrBytes); 95 | } catch(UnknownHostException e) { 96 | e.printStackTrace(); 97 | throw new IllegalArgumentException("Invalid team ID: "+teamID); 98 | } 99 | this.teamID=teamID; 100 | } 101 | 102 | public int getQueueTimeout() { 103 | return queueTimeout; 104 | } 105 | 106 | public void setQueueTimeout(int queueTimeout) { 107 | checkClosed(); 108 | this.queueTimeout=queueTimeout; 109 | } 110 | 111 | public void addNetconsoleListener(NetconsoleListener listener) { 112 | listeners.add(listener); 113 | } 114 | 115 | public void removeNetconsoleListener(NetconsoleListener listener) { 116 | listeners.remove(listener); 117 | } 118 | 119 | public void close() { 120 | checkClosed(); 121 | if(sendDataSocket!=null) { 122 | sendDataSocket.close(); 123 | sendDataSocket=null; 124 | } 125 | if(sendDataThread!=null) { 126 | sendDataThread.interrupt(); 127 | sendDataThread=null; 128 | } 129 | if(receiveDataSocket!=null) { 130 | receiveDataSocket.close(); 131 | receiveDataSocket=null; 132 | } 133 | if(receiveDataThread!=null) { 134 | receiveDataThread.interrupt(); 135 | receiveDataThread=null; 136 | } 137 | listeners.clear(); 138 | listeners=null; 139 | netconsoleMessages.clear(); 140 | netconsoleMessages=null; 141 | sendDataQueue.clear(); 142 | sendDataQueue=null; 143 | closed=true; 144 | } 145 | 146 | private void checkClosed() { 147 | if(closed) { 148 | throw new IllegalStateException("Communication has been closed"); 149 | } 150 | } 151 | 152 | /** 153 | * If fail to open send socket, send operations will be silently consumed 154 | * rather than closing the whole thing down. 155 | */ 156 | private void initSockets() { 157 | try { 158 | sendDataSocket=new DatagramSocket(); 159 | sendDataSocket.setReuseAddress(true); 160 | sendDataSocket.setBroadcast(true); 161 | } catch(SocketException e) { 162 | e.printStackTrace(); 163 | System.err.println("Failed to create netconsole send socket."); 164 | sendDataSocket=null; 165 | } 166 | try { 167 | receiveDataSocket=new DatagramSocket(RECV_PORT); 168 | receiveDataSocket.setReuseAddress(true); 169 | } catch(SocketException e) { 170 | e.printStackTrace(); 171 | System.err.println("Failed to create netconsole receive socket."); 172 | sendDataSocket=null; 173 | } 174 | } 175 | 176 | private void initThreads() { 177 | sendDataThread=new Thread(new SendDataWorker(),"Netconsole Send"); 178 | sendDataThread.start(); 179 | receiveDataThread=new Thread(new ReceiveDataWorker(), 180 | "Netconsole Receive"); 181 | receiveDataThread.start(); 182 | } 183 | 184 | private class SendDataWorker implements Runnable { 185 | @Override 186 | public void run() { 187 | while(sendDataSocket!=null&&!Thread.interrupted()&&!closed) { 188 | String sendData=null; 189 | try { 190 | sendData=sendDataQueue.take(); 191 | } catch(InterruptedException e) { 192 | break; 193 | } 194 | int len=sendData.length(); 195 | if(len==0||sendData.charAt(len-1)!='\n') { 196 | sendData+='\n'; 197 | } 198 | byte[] sendBytes=sendData.getBytes(); 199 | DatagramPacket packet=new DatagramPacket(sendBytes, 200 | sendBytes.length); 201 | packet.setAddress(broadcastAddress); 202 | packet.setPort(SEND_PORT); 203 | try { 204 | sendDataSocket.send(packet); 205 | } catch(IOException e) { 206 | e.printStackTrace(); 207 | } 208 | NetconsoleMessage msg=new NetconsoleMessage(DataDir.TOROBOT, 209 | sendData); 210 | netconsoleMessages.add(msg); 211 | synchronized(listeners) { 212 | for(NetconsoleListener listener:listeners) { 213 | listener.dataSent(msg); 214 | } 215 | } 216 | } 217 | } 218 | } 219 | 220 | private class ReceiveDataWorker implements Runnable { 221 | @Override 222 | public void run() { 223 | while(receiveDataSocket!=null&&!Thread.interrupted()&&!closed) { 224 | int length=1024; 225 | byte[] buffer=new byte[length]; 226 | DatagramPacket packet=new DatagramPacket(buffer,length); 227 | try { 228 | receiveDataSocket.receive(packet); 229 | } catch(SocketException e) { 230 | break; 231 | } catch(IOException e) { 232 | e.printStackTrace(); 233 | } 234 | if(paused) { 235 | continue; 236 | } 237 | String data=new String(buffer,0,packet.getLength()); 238 | NetconsoleMessage msg=new NetconsoleMessage(DataDir.TODS,data); 239 | netconsoleMessages.add(msg); 240 | synchronized(listeners) { 241 | for(NetconsoleListener listener:listeners) { 242 | listener.receivedData(msg); 243 | } 244 | } 245 | } 246 | } 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/gui/OperationPanel.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.gui; 2 | 3 | import java.awt.Dimension; 4 | import java.awt.BorderLayout; 5 | import java.awt.Font; 6 | import java.awt.event.ItemEvent; 7 | import java.awt.event.ItemListener; 8 | import javax.swing.SwingConstants; 9 | import javax.swing.JPanel; 10 | import javax.swing.JTextArea; 11 | import javax.swing.JSeparator; 12 | import javax.swing.JRadioButton; 13 | import javax.swing.JLabel; 14 | import javax.swing.JProgressBar; 15 | import javax.swing.JComboBox; 16 | import javax.swing.DefaultComboBoxModel; 17 | import javax.swing.ButtonGroup; 18 | import javax.swing.border.EtchedBorder; 19 | import javax.swing.border.TitledBorder; 20 | import com.jgoodies.forms.layout.FormLayout; 21 | import com.jgoodies.forms.layout.ColumnSpec; 22 | import com.jgoodies.forms.layout.RowSpec; 23 | import com.jgoodies.forms.factories.FormFactory; 24 | import org.anidev.frcds.common.DriverStation; 25 | import org.anidev.frcds.pc.DriverStationMain; 26 | import org.anidev.frcds.proto.torobot.OperationMode; 27 | import org.anidev.frcds.proto.torobot.TeamStation; 28 | 29 | /** 30 | * JPanel for the Operation tab 31 | */ 32 | public class OperationPanel extends JPanel { 33 | private static final String TELEOP_CMD="teleop"; 34 | private static final String AUTONOMOUS_CMD="auto"; 35 | private static final String PRACTICE_CMD="practice"; 36 | private static final String TEST_CMD="test"; 37 | private ButtonGroup operationModeGroup=new ButtonGroup(); 38 | private JLabel elapsedTimeValue; 39 | private JComboBox teamStationBox; 40 | private JProgressBar batteryBar; 41 | private JLabel teamIDText; 42 | private JRadioButton teleopRadio; 43 | private JRadioButton autonomousRadio; 44 | private JRadioButton practiceRadio; 45 | private JTextArea lcdTextArea; 46 | private JRadioButton testRadio; 47 | 48 | /** 49 | * add the initial contents to the panel 50 | */ 51 | public OperationPanel() { 52 | setPreferredSize(new Dimension(600,240)); 53 | setSize(new Dimension(600,240)); 54 | FormLayout formLayout=new FormLayout(new ColumnSpec[] { 55 | ColumnSpec.decode("180px"),ColumnSpec.decode("5px"), 56 | ColumnSpec.decode("default:grow"),},new RowSpec[] { 57 | RowSpec.decode("0px:grow(0.45)"),RowSpec.decode("5px"), 58 | RowSpec.decode("0px:grow(0.55)"),}); 59 | formLayout.setHonorsVisibility(false); 60 | setLayout(formLayout); 61 | 62 | JPanel topControlPanel=new JPanel(); 63 | add(topControlPanel,"1, 1, fill, fill"); 64 | topControlPanel.setLayout(new FormLayout(new ColumnSpec[] { 65 | ColumnSpec.decode("20px"),ColumnSpec.decode("default:grow"),}, 66 | new RowSpec[] {FormFactory.GLUE_ROWSPEC, 67 | FormFactory.GLUE_ROWSPEC,FormFactory.GLUE_ROWSPEC, 68 | FormFactory.GLUE_ROWSPEC,})); 69 | 70 | ItemListener modeListener=new ItemListener() { 71 | /* (non-Javadoc) 72 | * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent) 73 | */ 74 | @Override 75 | public void itemStateChanged(ItemEvent e) { 76 | if(e.getStateChange()!=ItemEvent.SELECTED) { 77 | return; 78 | } 79 | OperationMode mode=getMode(); 80 | DriverStation ds=DriverStationMain.getDS(); 81 | ds.setMode(mode); 82 | } 83 | }; 84 | 85 | teleopRadio=new JRadioButton("Teleoperated"); 86 | teleopRadio.setActionCommand(TELEOP_CMD); 87 | teleopRadio.setSelected(true); 88 | teleopRadio.addItemListener(modeListener); 89 | operationModeGroup.add(teleopRadio); 90 | teleopRadio.setHorizontalAlignment(SwingConstants.LEFT); 91 | topControlPanel.add(teleopRadio,"2, 1"); 92 | 93 | autonomousRadio=new JRadioButton("Autonomous"); 94 | autonomousRadio.setActionCommand(AUTONOMOUS_CMD); 95 | autonomousRadio.addItemListener(modeListener); 96 | operationModeGroup.add(autonomousRadio); 97 | autonomousRadio.setHorizontalAlignment(SwingConstants.LEFT); 98 | topControlPanel.add(autonomousRadio,"2, 2"); 99 | 100 | testRadio=new JRadioButton("Test"); 101 | testRadio.setActionCommand(TEST_CMD); 102 | testRadio.addItemListener(modeListener); 103 | operationModeGroup.add(testRadio); 104 | testRadio.setHorizontalAlignment(SwingConstants.LEFT); 105 | topControlPanel.add(testRadio,"2, 3"); 106 | 107 | practiceRadio=new JRadioButton("Practice"); 108 | practiceRadio.setToolTipText("Not currently implemented"); 109 | practiceRadio.setEnabled(false); 110 | practiceRadio.setActionCommand(PRACTICE_CMD); 111 | practiceRadio.addItemListener(modeListener); 112 | operationModeGroup.add(practiceRadio); 113 | practiceRadio.setHorizontalAlignment(SwingConstants.LEFT); 114 | topControlPanel.add(practiceRadio,"2, 4"); 115 | 116 | JPanel lcdPanel=new JPanel(); 117 | lcdPanel.setBorder(new TitledBorder(null,"User Messages", 118 | TitledBorder.LEADING,TitledBorder.TOP,null,null)); 119 | add(lcdPanel,"3, 1, 1, 3, fill, fill"); 120 | lcdPanel.setLayout(new BorderLayout(0,0)); 121 | 122 | lcdTextArea=new JTextArea(); 123 | lcdTextArea.setEditable(false); 124 | lcdTextArea.setText("This is a test message."); 125 | lcdTextArea.setFont(new Font("Monospaced",Font.PLAIN,12)); 126 | lcdPanel.add(lcdTextArea,BorderLayout.CENTER); 127 | 128 | JSeparator controlPanelSeparator=new JSeparator(); 129 | add(controlPanelSeparator,"1, 2, default, center"); 130 | 131 | JPanel bottomControlPanel=new JPanel(); 132 | add(bottomControlPanel,"1, 3, fill, fill"); 133 | bottomControlPanel.setLayout(new FormLayout(new ColumnSpec[] { 134 | FormFactory.GLUE_COLSPEC,ColumnSpec.decode("5px"), 135 | FormFactory.GLUE_COLSPEC,},new RowSpec[] { 136 | FormFactory.GLUE_ROWSPEC,FormFactory.GLUE_ROWSPEC, 137 | FormFactory.GLUE_ROWSPEC,FormFactory.GLUE_ROWSPEC,})); 138 | 139 | JLabel elapsedTimeLabel=new JLabel("Elapsed Time"); 140 | elapsedTimeLabel.setHorizontalAlignment(SwingConstants.RIGHT); 141 | bottomControlPanel.add(elapsedTimeLabel,"1, 1"); 142 | 143 | elapsedTimeValue=new JLabel(); 144 | elapsedTimeValue.setBorder(new EtchedBorder(EtchedBorder.LOWERED,null, 145 | null)); 146 | elapsedTimeValue.setFont(new Font("Monospaced",Font.PLAIN,16)); 147 | elapsedTimeValue.setHorizontalAlignment(SwingConstants.LEFT); 148 | setElapsedTime(0); 149 | bottomControlPanel.add(elapsedTimeValue,"3, 1"); 150 | 151 | JLabel teamIDLabel=new JLabel("Team ID"); 152 | teamIDLabel.setHorizontalAlignment(SwingConstants.RIGHT); 153 | bottomControlPanel.add(teamIDLabel,"1, 2"); 154 | 155 | teamIDText=new JLabel(); 156 | teamIDText.setHorizontalAlignment(SwingConstants.CENTER); 157 | setTeamID(-1); 158 | bottomControlPanel.add(teamIDText,"3, 2"); 159 | 160 | JLabel teamStationLabel=new JLabel("Team Station"); 161 | teamStationLabel.setHorizontalAlignment(SwingConstants.RIGHT); 162 | bottomControlPanel.add(teamStationLabel,"1, 3"); 163 | 164 | teamStationBox=new JComboBox(); 165 | teamStationBox.setModel(new DefaultComboBoxModel( 166 | TeamStation.values())); 167 | bottomControlPanel.add(teamStationBox,"3, 3, fill, default"); 168 | 169 | JLabel batteryLabel=new JLabel("PC Battery"); 170 | batteryLabel.setHorizontalAlignment(SwingConstants.RIGHT); 171 | bottomControlPanel.add(batteryLabel,"1, 4"); 172 | 173 | batteryBar=new JProgressBar(); 174 | batteryBar.setStringPainted(true); 175 | setBatteryPercent(-1.0); 176 | bottomControlPanel.add(batteryBar,"3, 4"); 177 | } 178 | 179 | /** 180 | * @param elapsedTimeMs the elapsed time in milliseconds 181 | */ 182 | public void setElapsedTime(double elapsedTimeMs) { 183 | double seconds=elapsedTimeMs/1000; 184 | int minutes=(int)Math.floor(seconds/60); 185 | int roundSeconds=(int)Math.floor(seconds%60); 186 | int deciSeconds=(int)Math.floor(seconds*10)%10; 187 | String roundSecondsText=String.format("%02d",roundSeconds); 188 | String text=minutes+":"+roundSecondsText+"."+deciSeconds; 189 | elapsedTimeValue.setText(text); 190 | } 191 | 192 | /** 193 | * @param percent the battery percentage 194 | */ 195 | public void setBatteryPercent(double percent) { 196 | if(percent<0) { 197 | batteryBar.setValue(0); 198 | batteryBar.setString("Unavailable"); 199 | } else { 200 | int val=(int)Math.round(percent*100); 201 | batteryBar.setValue(val); 202 | // batteryBar.setString(null); 203 | batteryBar.setString(val+"% \u26A1"); 204 | } 205 | } 206 | 207 | /** 208 | * @param id the team ID 209 | */ 210 | public void setTeamID(int id) { 211 | if(id<=0) { 212 | teamIDText.setText("—"); 213 | } else { 214 | teamIDText.setText(Integer.toString(id)); 215 | } 216 | } 217 | 218 | /** 219 | * @return the current OperationMode 220 | */ 221 | public OperationMode getMode() { 222 | if(autonomousRadio.isSelected()) { 223 | return OperationMode.AUTONOMOUS; 224 | } else if(testRadio.isSelected()) { 225 | return OperationMode.TEST; 226 | } else { 227 | return OperationMode.TELEOPERATED; 228 | } 229 | } 230 | 231 | /** 232 | * @return the TeamStation that was selected 233 | */ 234 | public TeamStation getStation() { 235 | return (TeamStation)teamStationBox.getSelectedItem(); 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/input/InputEnvironment.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.input; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.security.MessageDigest; 5 | import java.security.NoSuchAlgorithmException; 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.HashMap; 9 | import java.util.HashSet; 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.Set; 13 | import java.util.logging.Logger; 14 | import net.java.games.input.Component; 15 | import net.java.games.input.Controller; 16 | import net.java.games.input.ControllerEnvironment; 17 | 18 | /** 19 | * The environment of the input devices 20 | */ 21 | public class InputEnvironment { 22 | public static final int NUM_DEVICES=4; 23 | private static MessageDigest digest=null; 24 | private String[] deviceHashes=new String[] {null,null,null,null}; 25 | private Map deviceMap=Collections 26 | .synchronizedMap(new HashMap()); 27 | private Map oldPositionMap=Collections 28 | .synchronizedMap(new HashMap()); 29 | private List listeners=Collections 30 | .synchronizedList(new ArrayList()); 31 | static { 32 | try { 33 | digest=MessageDigest.getInstance("MD5"); 34 | } catch(NoSuchAlgorithmException e) { 35 | // MD5 should exist in all implementations 36 | e.printStackTrace(); 37 | System.exit(1); 38 | } 39 | } 40 | 41 | /** 42 | * Set up the logger and update the controllers 43 | */ 44 | public InputEnvironment() { 45 | Logger.getLogger("net.java.games.input").setUseParentHandlers(false); 46 | updateControllers(); 47 | } 48 | 49 | /** 50 | * @param listener the listener to add 51 | */ 52 | public void addInputListener(InputListener listener) { 53 | listeners.add(listener); 54 | } 55 | 56 | /** 57 | * @param listener the listener to remove 58 | */ 59 | public void removeInputListener(InputListener listener) { 60 | listeners.remove(listener); 61 | } 62 | 63 | /** 64 | * @return the map of the input devices 65 | */ 66 | public synchronized Map getDeviceMap() { 67 | return Collections.unmodifiableMap(deviceMap); 68 | } 69 | 70 | /** 71 | * @param index the index of the device 72 | * @return the device at that index or null if the index is not valid 73 | */ 74 | public synchronized InputDevice getDevice(int index) { 75 | if(index<0||index>3) { 76 | return null; 77 | } 78 | String hash=deviceHashes[index]; 79 | if(hash==null) { 80 | return null; 81 | } 82 | return deviceMap.get(hash); 83 | } 84 | 85 | /** 86 | * @param hash the hash of the input device 87 | * @return the input device with that hash 88 | */ 89 | public synchronized InputDevice getDevice(String hash) { 90 | return deviceMap.get(hash); 91 | } 92 | 93 | /** 94 | * @param index the index of the device hash 95 | * @return hash the hash at that index 96 | */ 97 | public synchronized String getDeviceHash(int index) { 98 | if(index<0||index>3) { 99 | return null; 100 | } 101 | return deviceHashes[index]; 102 | } 103 | 104 | /** 105 | * The two devices switch places 106 | * @param index1 the index of the first device 107 | * @param index2 the index of the second device 108 | */ 109 | public synchronized void swapDevices(int index1,int index2) { 110 | String hash1=deviceHashes[index1]; 111 | String hash2=deviceHashes[index2]; 112 | deviceHashes[index1]=hash2; 113 | deviceHashes[index2]=hash1; 114 | } 115 | 116 | /** 117 | * @param index the index to put the device in 118 | * @param hash the hash of the device 119 | */ 120 | public synchronized void setDevice(int index,String hash) { 121 | if(!deviceMap.containsKey(hash)) { 122 | throw new IllegalArgumentException("Device hash "+hash 123 | +" does not exist"); 124 | } 125 | deviceHashes[index]=hash; 126 | } 127 | 128 | /** 129 | * @param index the index of the device to unset 130 | */ 131 | public synchronized void unsetDevice(int index) { 132 | deviceHashes[index]=null; 133 | } 134 | 135 | /** 136 | * Force the controllers to be updated because by default, 137 | * the ControllerEnvironment only scans controllers once and 138 | * caches them for all future instantiations 139 | */ 140 | public synchronized void updateControllers() { 141 | ControllerEnvironment env=null; 142 | try { 143 | // The following hack is to force controllers to be updated 144 | // because by default, the ControllerEnvironment only scans 145 | // controllers once and caches them for all future instantiations 146 | Class clazz=Class 147 | .forName("net.java.games.input.DefaultControllerEnvironment"); 148 | Constructor defaultConstructor=clazz.getDeclaredConstructor(); 149 | defaultConstructor.setAccessible(true); // set visibility to public 150 | env=(ControllerEnvironment)defaultConstructor.newInstance(); 151 | } catch(Exception e) { 152 | e.printStackTrace(); 153 | } 154 | Controller[] controllers=env.getControllers(); 155 | Set oldKeys=new HashSet<>(deviceMap.keySet()); 156 | Set processedKeys=new HashSet<>(); 157 | synchronized(listeners) { 158 | for(Controller controller:controllers) { 159 | processController(controller,processedKeys); 160 | } 161 | } 162 | processDevicesRemoved(oldKeys,processedKeys); 163 | } 164 | 165 | /** 166 | * Add an input device with the controller to the environment 167 | * @param controller the controller to process 168 | * @param procesedKeys the set to add the controller's hash to 169 | */ 170 | private void processController(Controller controller, 171 | Set procesedKeys) { 172 | String controllerStr=stringifyController(controller); 173 | String controllerHash=hashToString(makeHash(controllerStr)); 174 | procesedKeys.add(controllerHash); 175 | if(deviceMap.containsKey(controllerHash)) { 176 | return; 177 | } 178 | InputDevice dev=new InputDevice(controller); 179 | deviceMap.put(controllerHash,dev); 180 | if(dev.getType()==Type.UNKNOWN) { 181 | return; 182 | } 183 | if(oldPositionMap.containsKey(controllerHash)) { 184 | int oldPosition=oldPositionMap.get(controllerHash); 185 | if(oldPosition>=0&&oldPosition<=3&&deviceHashes[oldPosition]==null) { 186 | deviceHashes[oldPosition]=controllerHash; 187 | oldPositionMap.remove(controllerHash); 188 | } 189 | } else { 190 | for(int i=0;i oldKeys, 208 | Set processedKeys) { 209 | oldKeys.removeAll(processedKeys); 210 | if(oldKeys.size()==0) { 211 | return; 212 | } 213 | synchronized(listeners) { 214 | for(String hash:oldKeys) { 215 | for(int i=0;i tabList=Arrays.asList(DEF_TAB_LIST); 202 | for(String tabName:tabOrder) { 203 | int i=tabList.indexOf(tabName); 204 | if(i>=0) { 205 | TabInfo tab=tabs[i]; 206 | tabbedPane.addTab(tab.name,null,tab.instance,tab.tooltip); 207 | } 208 | } 209 | String selectedTab=getPrefs().get(SELECTED_TAB_PREF, 210 | tabs[DEF_SELECTED_TAB].name); 211 | int selectedTabIndex=tabbedPane.indexOfTab(selectedTab); 212 | if(selectedTabIndex>=0) { 213 | tabbedPane.setSelectedIndex(selectedTabIndex); 214 | } 215 | } 216 | 217 | /** 218 | * @return preferences of DriverStationFrame 219 | */ 220 | private static Preferences getPrefs() { 221 | return Utils.getPrefs(DriverStationFrame.class); 222 | } 223 | 224 | /** 225 | * @return string array containing the name of each tab 226 | */ 227 | private static String[] initDefTabList() { 228 | StringBuilder defTabListBuilder=new StringBuilder(); 229 | for(TabInfo tab:tabs) { 230 | defTabListBuilder.append(tab.name); 231 | defTabListBuilder.append(','); 232 | } 233 | return defTabListBuilder.toString().split(","); 234 | } 235 | 236 | /** 237 | * @return a String array of the tabs in their prefered order 238 | */ 239 | private static String[] getTabOrderPref() { 240 | Preferences prefs=getPrefs(); 241 | String tabOrderStr=prefs.get(TAB_ORDER_PREF,""); 242 | String[] tabOrderList=tabOrderStr.split(","); 243 | if(tabOrderList.length!=tabs.length) { 244 | tabOrderList=DEF_TAB_LIST; 245 | } 246 | return tabOrderList; 247 | } 248 | 249 | /** 250 | * info for a tab 251 | */ 252 | private static class TabInfo { 253 | public String name; 254 | public String tooltip; 255 | public JPanel instance; 256 | 257 | /** 258 | * @param name the name of the tab 259 | * @param tooltip the tooltip of the tab 260 | */ 261 | public TabInfo(String name,String tooltip) { 262 | this.name=name; 263 | this.tooltip=tooltip; 264 | } 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /java/FRC-DriverStation-PC/src/main/java/org/anidev/frcds/pc/gui/SetupPanel.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.pc.gui; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Dimension; 5 | import java.awt.datatransfer.DataFlavor; 6 | import java.awt.datatransfer.Transferable; 7 | import java.awt.datatransfer.UnsupportedFlavorException; 8 | import java.awt.event.ActionEvent; 9 | import java.awt.event.ActionListener; 10 | import java.io.IOException; 11 | import javax.activation.ActivationDataFlavor; 12 | import javax.swing.DefaultComboBoxModel; 13 | import javax.swing.DropMode; 14 | import javax.swing.JComboBox; 15 | import javax.swing.JComponent; 16 | import javax.swing.JPanel; 17 | import javax.swing.JScrollPane; 18 | import javax.swing.JTable; 19 | import javax.swing.ListSelectionModel; 20 | import javax.swing.TransferHandler; 21 | import javax.swing.border.TitledBorder; 22 | import javax.swing.table.AbstractTableModel; 23 | import org.anidev.frcds.pc.input.InputDevice; 24 | import org.anidev.frcds.pc.input.InputEnvironment; 25 | import org.anidev.frcds.pc.input.InputListener; 26 | import org.anidev.frcds.pc.input.Type; 27 | import com.jgoodies.forms.layout.ColumnSpec; 28 | import com.jgoodies.forms.layout.FormLayout; 29 | import com.jgoodies.forms.layout.RowSpec; 30 | 31 | /** 32 | * JPanel for the setup tab 33 | */ 34 | public class SetupPanel extends JPanel { 35 | public static final String ROBORIO_PROTOCOL="2015 roboRIO protocol"; 36 | public static final String CRIO_PROTOCOL="2009-2014 cRIO protocol"; 37 | private static final DataFlavor INPUT_FLAVOR=new ActivationDataFlavor( 38 | Integer.class,"Device Index"); 39 | private InputEnvironment env; 40 | private JTable inputTable; 41 | private AbstractTableModel inputTableModel; 42 | private JComboBox protocolMenu; 43 | 44 | /** 45 | * Setup the setup 46 | * 47 | * @param _env 48 | * the InputEnvironment with the input devices 49 | */ 50 | public SetupPanel(InputEnvironment _env) { 51 | this.env=_env; 52 | 53 | setPreferredSize(new Dimension(600,240)); 54 | setSize(new Dimension(600,240)); 55 | setLayout(new FormLayout(new ColumnSpec[] {ColumnSpec 56 | .decode("min:grow")},new RowSpec[] { 57 | RowSpec.decode("default:grow"),RowSpec.decode("min:grow")})); 58 | 59 | JPanel inputPanel=new JPanel(); 60 | inputPanel.setBorder(new TitledBorder(null,"Input", 61 | TitledBorder.LEADING,TitledBorder.TOP,null,null)); 62 | add(inputPanel,"1, 1, fill, fill"); 63 | inputPanel.setLayout(new BorderLayout(0,0)); 64 | 65 | inputTable=new JTable(); 66 | inputTable.setDragEnabled(true); 67 | inputTable.setDropMode(DropMode.ON); 68 | inputTable.setFillsViewportHeight(true); 69 | inputTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 70 | inputTableModel=new InputTableModel(); 71 | inputTable.setModel(inputTableModel); 72 | inputTable.setTransferHandler(new InputTransferHandler()); 73 | 74 | JScrollPane inputScrollPane=new JScrollPane(inputTable); 75 | inputPanel.add(inputScrollPane); 76 | 77 | env.addInputListener(new InputListener() { 78 | /* (non-Javadoc) 79 | * @see org.anidev.frcds.pc.input.InputListener#deviceAdded(org.anidev.frcds.pc.input.InputDevice) 80 | */ 81 | @Override 82 | public void deviceAdded(InputDevice dev) { 83 | inputTableModel.fireTableDataChanged(); 84 | } 85 | 86 | /* (non-Javadoc) 87 | * @see org.anidev.frcds.pc.input.InputListener#deviceRemoved(org.anidev.frcds.pc.input.InputDevice) 88 | */ 89 | @Override 90 | public void deviceRemoved(InputDevice dev) { 91 | inputTableModel.fireTableDataChanged(); 92 | } 93 | }); 94 | 95 | // drop down menu to switch between protocols 96 | protocolMenu=new JComboBox(); 97 | protocolMenu.setModel(new DefaultComboBoxModel(new String[] { 98 | CRIO_PROTOCOL,ROBORIO_PROTOCOL})); 99 | protocolMenu.addActionListener(new ActionListener() { 100 | /* (non-Javadoc) 101 | * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) 102 | */ 103 | @Override 104 | public void actionPerformed(ActionEvent event) { 105 | if(protocolMenu.getSelectedItem().equals(CRIO_PROTOCOL)) { 106 | // TODO put code to switch to the cRIO protocol here 107 | } else if(protocolMenu.getSelectedItem().equals( 108 | ROBORIO_PROTOCOL)) { 109 | // TODO switch to the new roboRIO protocol here 110 | } 111 | } 112 | }); 113 | add(protocolMenu,"1, 2, default, default"); 114 | } 115 | 116 | /** 117 | * @return the communications protocol that was selected 118 | */ 119 | public String getProtocol() { 120 | return protocolMenu.getSelectedItem().toString(); 121 | } 122 | 123 | /** 124 | * table for the input devices 125 | */ 126 | private class InputTableModel extends AbstractTableModel { 127 | /* (non-Javadoc) 128 | * @see javax.swing.table.TableModel#getRowCount() 129 | */ 130 | @Override 131 | public int getRowCount() { 132 | return 4; 133 | } 134 | 135 | /* (non-Javadoc) 136 | * @see javax.swing.table.TableModel#getColumnCount() 137 | */ 138 | @Override 139 | public int getColumnCount() { 140 | return 2; 141 | } 142 | 143 | /* (non-Javadoc) 144 | * @see javax.swing.table.AbstractTableModel#getColumnName(int) 145 | */ 146 | @Override 147 | public String getColumnName(int columnIndex) { 148 | switch(columnIndex) { 149 | case 0: 150 | return "Device"; 151 | case 1: 152 | return "Type"; 153 | } 154 | return null; 155 | } 156 | 157 | /* (non-Javadoc) 158 | * @see javax.swing.table.AbstractTableModel#getColumnClass(int) 159 | */ 160 | @Override 161 | public Class getColumnClass(int columnIndex) { 162 | switch(columnIndex) { 163 | case 0: 164 | return String.class; 165 | case 1: 166 | return Type.class; 167 | } 168 | return null; 169 | } 170 | 171 | /* (non-Javadoc) 172 | * @see javax.swing.table.AbstractTableModel#isCellEditable(int, int) 173 | */ 174 | @Override 175 | public boolean isCellEditable(int rowIndex,int columnIndex) { 176 | return false; 177 | } 178 | 179 | /* (non-Javadoc) 180 | * @see javax.swing.table.TableModel#getValueAt(int, int) 181 | */ 182 | @Override 183 | public Object getValueAt(int rowIndex,int columnIndex) { 184 | InputDevice dev=env.getDevice(rowIndex); 185 | if(dev==null) { 186 | return null; 187 | } 188 | switch(columnIndex) { 189 | case 0: 190 | return dev.getController().getName(); 191 | case 1: 192 | return dev.getType(); 193 | } 194 | return null; 195 | } 196 | } 197 | 198 | /** 199 | * TransferHandler for moving the input devices 200 | */ 201 | private class InputTransferHandler extends TransferHandler { 202 | /* (non-Javadoc) 203 | * @see javax.swing.TransferHandler#getSourceActions(javax.swing.JComponent) 204 | */ 205 | @Override 206 | public int getSourceActions(JComponent c) { 207 | return MOVE; 208 | } 209 | 210 | /* (non-Javadoc) 211 | * @see javax.swing.TransferHandler#createTransferable(javax.swing.JComponent) 212 | */ 213 | @Override 214 | protected Transferable createTransferable(JComponent c) { 215 | if(c!=inputTable) { 216 | return null; 217 | } 218 | return new InputTransferable(inputTable.getSelectedRow()); 219 | } 220 | 221 | /* (non-Javadoc) 222 | * @see javax.swing.TransferHandler#canImport(javax.swing.TransferHandler.TransferSupport) 223 | */ 224 | @Override 225 | public boolean canImport(TransferSupport support) { 226 | boolean b=support.getComponent()==inputTable; 227 | b&=support.isDrop(); 228 | b&=support.isDataFlavorSupported(INPUT_FLAVOR); 229 | return b; 230 | } 231 | 232 | /* (non-Javadoc) 233 | * @see javax.swing.TransferHandler#importData(javax.swing.TransferHandler.TransferSupport) 234 | */ 235 | @Override 236 | public boolean importData(TransferSupport support) { 237 | if(!canImport(support)) { 238 | return false; 239 | } 240 | Transferable trans=support.getTransferable(); 241 | int fromIndex=0; 242 | try { 243 | fromIndex=(Integer)trans.getTransferData(INPUT_FLAVOR); 244 | } catch(IOException|UnsupportedFlavorException e) { 245 | e.printStackTrace(); 246 | return false; 247 | } 248 | JTable.DropLocation location=(JTable.DropLocation)support 249 | .getDropLocation(); 250 | int toIndex=location.getRow(); 251 | env.swapDevices(fromIndex,toIndex); 252 | inputTableModel.fireTableDataChanged(); 253 | return true; 254 | } 255 | } 256 | 257 | /** 258 | * Transferable for input devices 259 | */ 260 | private class InputTransferable implements Transferable { 261 | public int index; 262 | 263 | /** 264 | * @param index 265 | * the input device's index 266 | */ 267 | public InputTransferable(int index) { 268 | this.index=index; 269 | } 270 | 271 | /* (non-Javadoc) 272 | * @see java.awt.datatransfer.Transferable#getTransferDataFlavors() 273 | */ 274 | @Override 275 | public DataFlavor[] getTransferDataFlavors() { 276 | return new DataFlavor[] {INPUT_FLAVOR}; 277 | } 278 | 279 | /* (non-Javadoc) 280 | * @see java.awt.datatransfer.Transferable#isDataFlavorSupported(java.awt.datatransfer.DataFlavor) 281 | */ 282 | @Override 283 | public boolean isDataFlavorSupported(DataFlavor flavor) { 284 | return false; 285 | } 286 | 287 | /* (non-Javadoc) 288 | * @see java.awt.datatransfer.Transferable#getTransferData(java.awt.datatransfer.DataFlavor) 289 | */ 290 | @Override 291 | public Object getTransferData(DataFlavor flavor) { 292 | if(INPUT_FLAVOR.equals(flavor)) { 293 | return index; 294 | } 295 | return null; 296 | } 297 | } 298 | } 299 | -------------------------------------------------------------------------------- /java/FRCDS-Java-Comm/src/main/java/org/anidev/frcds/proto/torobot/FRCCommonControl.java: -------------------------------------------------------------------------------- 1 | package org.anidev.frcds.proto.torobot; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ShortBuffer; 6 | import java.util.Arrays; 7 | import java.util.zip.CRC32; 8 | import org.anidev.frcds.proto.CommData; 9 | import org.anidev.frcds.proto.ControlFlags; 10 | import org.anidev.frcds.proto.DataDir; 11 | import org.anidev.frcds.proto.Version; 12 | 13 | public class FRCCommonControl extends CommData { 14 | public static final int SIZE=1024; 15 | public static final Version CURRENT_VERSION=new Version("12191200"); 16 | private static int totalPackets=0; 17 | private int packetIndex=++totalPackets; 18 | private ControlFlags control=new ControlFlags(); 19 | private DigitalInputs digitalInputs=new DigitalInputs(); 20 | private int teamID=0; 21 | private Alliance alliance=Alliance.RED; 22 | private char position='1'; 23 | private Joystick[] joysticks=new Joystick[] {new Joystick(),new Joystick(), 24 | new Joystick(),new Joystick()}; 25 | private AnalogInputs analogInputs=new AnalogInputs(); 26 | private CRIOChecksum crioChecksum=new CRIOChecksum(); 27 | private FPGAChecksum fpgaChecksum=new FPGAChecksum(); 28 | private Version version=CURRENT_VERSION; 29 | 30 | public static int getTotalPackets() { 31 | return totalPackets; 32 | } 33 | 34 | public int getPacketIndex() { 35 | return packetIndex; 36 | } 37 | 38 | public void setPacketIndex(int packetIndex) { 39 | this.packetIndex=packetIndex; 40 | } 41 | 42 | public ControlFlags getControlFlags() { 43 | return control; 44 | } 45 | 46 | public void setControlFlags(ControlFlags control) { 47 | this.control=control; 48 | } 49 | 50 | public DigitalInputs getDigitalInputs() { 51 | return digitalInputs; 52 | } 53 | 54 | public void setDigitalInputs(DigitalInputs digitalInputs) { 55 | this.digitalInputs=digitalInputs; 56 | } 57 | 58 | public int getTeamID() { 59 | return teamID; 60 | } 61 | 62 | public void setTeamID(int teamID) { 63 | this.teamID=teamID; 64 | } 65 | 66 | public Alliance getAlliance() { 67 | return alliance; 68 | } 69 | 70 | public void setAlliance(Alliance alliance) { 71 | this.alliance=alliance; 72 | } 73 | 74 | public char getPosition() { 75 | return position; 76 | } 77 | 78 | public void setPosition(char position) { 79 | this.position=position; 80 | } 81 | 82 | public Joystick[] getJoysticks() { 83 | return joysticks; 84 | } 85 | 86 | public void setJoysticks(Joystick[] joysticks) { 87 | this.joysticks=joysticks; 88 | } 89 | 90 | public int getNumJoysticks() { 91 | return joysticks.length; 92 | } 93 | 94 | public Joystick getJoystick(int index) { 95 | return joysticks[index]; 96 | } 97 | 98 | public void setJoystick(int index,Joystick newJoystick) { 99 | joysticks[index]=newJoystick; 100 | } 101 | 102 | public AnalogInputs getAnalogInputs() { 103 | return analogInputs; 104 | } 105 | 106 | public void setAnalogInputs(AnalogInputs analogInputs) { 107 | this.analogInputs=analogInputs; 108 | } 109 | 110 | public CRIOChecksum getCrioChecksum() { 111 | return crioChecksum; 112 | } 113 | 114 | public void setCrioChecksum(CRIOChecksum crioChecksum) { 115 | this.crioChecksum=crioChecksum; 116 | } 117 | 118 | public FPGAChecksum getFpgaChecksum() { 119 | return fpgaChecksum; 120 | } 121 | 122 | public void setFpgaChecksum(FPGAChecksum fpgaChecksum) { 123 | this.fpgaChecksum=fpgaChecksum; 124 | } 125 | 126 | public Version getVersion() { 127 | return version; 128 | } 129 | 130 | public void setVersion(Version version) { 131 | this.version=version; 132 | } 133 | 134 | public TeamStation getTeamStation() { 135 | return getTeamStation(alliance,position); 136 | } 137 | 138 | public static TeamStation getTeamStation(Alliance alliance,char position) { 139 | switch(alliance) { 140 | case BLUE: 141 | switch(position) { 142 | case '1': 143 | return TeamStation.BLUE1; 144 | case '2': 145 | return TeamStation.BLUE2; 146 | case '3': 147 | return TeamStation.BLUE3; 148 | } 149 | break; 150 | case RED: 151 | switch(position) { 152 | case '1': 153 | return TeamStation.RED1; 154 | case '2': 155 | return TeamStation.RED2; 156 | case '3': 157 | return TeamStation.RED3; 158 | } 159 | } 160 | return null; 161 | } 162 | 163 | @Override 164 | public byte[] serialize() { 165 | ByteArrayOutputStream byteStream=new ByteArrayOutputStream(SIZE); 166 | ByteBuffer byteBuffer=ByteBuffer.allocate(2); 167 | byteBuffer.order(BYTE_ORDER); 168 | byteBuffer.putShort((short)packetIndex); 169 | byte[] packetIndexBytes=byteBuffer.array(); 170 | byteStream.write(packetIndexBytes,0,packetIndexBytes.length); 171 | byte[] controlBytes=control.serialize(DataDir.TOROBOT); 172 | byteStream.write(controlBytes,0,controlBytes.length); 173 | byte[] digitalInputsBytes=digitalInputs.serialize(); 174 | byteStream.write(digitalInputsBytes,0,digitalInputsBytes.length); 175 | byteBuffer.putShort(0,(short)teamID); 176 | byte[] teamIDBytes=byteBuffer.array(); 177 | byteStream.write(teamIDBytes,0,teamIDBytes.length); 178 | byteStream.write(new byte[] {(byte)alliance.getId()},0,1); 179 | byteStream.write(new byte[] {(byte)position},0,1); 180 | for(int i=0;i list=nc.getNetconsoleMessages(); 178 | StringBuilder text=new StringBuilder(); 179 | synchronized(list) { 180 | for(int i=lastCount;i0) { 187 | if(autoScrolling<0) { 188 | autoScrolling=0; 189 | } 190 | autoScrolling++; 191 | final boolean cachedListMode=listMode; 192 | SwingUtilities.invokeLater(new Runnable() { 193 | @Override 194 | public void run() { 195 | JScrollBar scrollBar=getScrollBar(cachedListMode); 196 | scrollBar.setValue(scrollBar.getMaximum()); 197 | autoScrolling--; 198 | } 199 | }); 200 | } 201 | lastCount=count; 202 | } 203 | 204 | public void firePanelDestroyed() { 205 | if(nc!=null) { 206 | nc.removeNetconsoleListener(ncListener); 207 | } 208 | } 209 | 210 | private void sendMessage() { 211 | String text=consoleSendText.getText(); 212 | nc.sendData(text); 213 | consoleSendText.setText(""); 214 | } 215 | 216 | public boolean isListMode() { 217 | return listMode; 218 | } 219 | 220 | public void setListMode(boolean listMode) { 221 | if(this.listMode==listMode) { 222 | return; 223 | } 224 | this.listMode=listMode; 225 | if(listMode) { 226 | messagesLayout.show(messagesPanel,"list"); 227 | } else { 228 | messagesLayout.show(messagesPanel,"text"); 229 | } 230 | controlBar.getListButton().setSelected(listMode); 231 | controlBar.getTextButton().setSelected(!listMode); 232 | JScrollBar scrollBar=getScrollBar(listMode); 233 | scrollBar.setValue(scrollBar.getMaximum()); 234 | } 235 | 236 | protected void setPaused(boolean paused) { 237 | nc.setPaused(paused); 238 | } 239 | 240 | private JScrollBar getScrollBar(boolean mode) { 241 | return (mode?tableScrollPane:textScrollPane).getVerticalScrollBar(); 242 | } 243 | 244 | private static boolean isScrollBarMaximum(JScrollBar scrollBar) { 245 | return scrollBar.getValue()+scrollBar.getVisibleAmount()>=scrollBar 246 | .getMaximum(); 247 | } 248 | 249 | private class NetconsoleTableModel extends AbstractTableModel { 250 | private Icon sentIcon; 251 | private Icon receivedIcon; 252 | private DateFormat dateFormat; 253 | 254 | public NetconsoleTableModel() { 255 | sentIcon=Utils.getIcon("arrow-up.png"); 256 | receivedIcon=Utils.getIcon("arrow-down.png"); 257 | dateFormat=DateFormat.getTimeInstance(); 258 | } 259 | 260 | @Override 261 | public int getRowCount() { 262 | if(nc==null) { 263 | return 0; 264 | } 265 | return nc.getNetconsoleMessages().size(); 266 | } 267 | 268 | @Override 269 | public int getColumnCount() { 270 | return 3; 271 | } 272 | 273 | @Override 274 | public String getColumnName(int columnIndex) { 275 | switch(columnIndex) { 276 | case 0: 277 | return ""; 278 | case 1: 279 | return "Message"; 280 | case 2: 281 | return "Time"; 282 | } 283 | return null; 284 | } 285 | 286 | @Override 287 | public Class getColumnClass(int columnIndex) { 288 | switch(columnIndex) { 289 | case 0: 290 | return Icon.class; 291 | case 1: 292 | case 2: 293 | return String.class; 294 | } 295 | return null; 296 | } 297 | 298 | @Override 299 | public boolean isCellEditable(int rowIndex,int columnIndex) { 300 | return false; 301 | } 302 | 303 | @Override 304 | public Object getValueAt(int rowIndex,int columnIndex) { 305 | if(nc==null) { 306 | return null; 307 | } 308 | NetconsoleMessage msg=nc.getNetconsoleMessage(rowIndex); 309 | switch(columnIndex) { 310 | case 0: 311 | if(msg.getDirection()==DataDir.TODS) { 312 | return receivedIcon; 313 | } else { 314 | return sentIcon; 315 | } 316 | case 1: 317 | return msg.getMessage(); 318 | case 2: 319 | return dateFormat.format(msg.getDate().getTime()); 320 | } 321 | return null; 322 | } 323 | } 324 | 325 | private class NetconsoleCellRenderer extends DefaultTableCellRenderer { 326 | @Override 327 | public Component getTableCellRendererComponent(JTable table, 328 | Object value,boolean isSelected,boolean hasFocus,int row, 329 | int column) { 330 | JLabel label=(JLabel)super.getTableCellRendererComponent(table, 331 | value,isSelected,hasFocus,row,column); 332 | String tooltip=label.getText(); 333 | label.setToolTipText(tooltip); 334 | return label; 335 | } 336 | } 337 | } 338 | --------------------------------------------------------------------------------