diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..de2a843
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "java.configuration.updateBuildConfiguration": "automatic"
+}
\ No newline at end of file
diff --git a/BSD_License_for_WPILib_code.txt b/BSD_License_for_WPILib_code.txt
new file mode 100644
index 0000000..3a7f798
--- /dev/null
+++ b/BSD_License_for_WPILib_code.txt
@@ -0,0 +1,24 @@
+* Copyright (c) 2009 FIRST
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the FIRST nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 6525af3..65edcf4 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,103 @@
# lib6647
-Team 6647's library to allow JSON-oriented object building and initialization.
+
+Team 6647's library for JSON-oriented object initialization, among other things.
+
+
+## Getting Started
+
+### Usage
+
+Team 6647 encourages the usage of this library by any team that may find it useful, period. Giving us credit is optional, but greatly appreciated. Please feel free to request anything your team might need that could be added to this library.
+
+### Compiling lib6647 to your Robot
+
+**lib6647** must be added as a dependency in your Robot's _build.gradle_ file, as well as the **json-simple** library that it requires.
+
+First, add the following url to your Maven repositories in _build.gradle_: https://jitpack.io. This is to effortlessly compile code from any github project release or commit into your code.
+
+Your _build.gradle_ file should look like this (if no other Maven repositories are present):
+
+```
+ repositories {
+ mavenCentral()
+ maven {
+ url 'https://jitpack.io'
+ }
+ }
+```
+
+Then, add **lib6647** and **json-simple** as a dependency in your _build.gradle_'s dependencies like so:
+
+```
+ // https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
+ compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
+
+ // lib6647
+ compile group: 'com.github.pacoito123', name: 'lib6647', version: '-SNAPSHOT'
+```
+
+Your dependencies in should look like this (again, if none other than WPILib's dependencies are present):
+
+```
+ dependencies {
+ // WPILib dependencies.
+ compile wpi.deps.wpilib()
+ compile wpi.deps.vendor.java()
+ nativeZip wpi.deps.vendor.jni(wpi.platforms.roborio)
+ nativeDesktopZip wpi.deps.vendor.jni(wpi.platforms.desktop)
+ testCompile 'junit:junit:4.12'
+
+ // https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
+ compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
+
+ // lib6647
+ compile group: 'com.github.pacoito123', name: 'lib6647', version: '-SNAPSHOT'
+ }
+```
+
+Of course, you can change the version of the library to any specific commit in any branch, just make sure that your code is compatible with it.
+
+Now you're ready to begin instantiating and initializing objects through JSON!
+
+## To do (for now)
+
+- [ ] Implement every HyperComponent Wrapper (if needed).
+ - [ ] HyperAHRS
+ - [ ] HyperAnalogPotentiometer
+ - [ ] HyperCompressor
+ - [ ] HyperDigitalInput
+ - [ ] HyperDoubleSolenoid
+ - [ ] HyperEncoder
+ - [ ] HyperPDP
+ - [x] HyperSolenoid
+ - [x] HyperTalon
+ - [ ] HyperUltrasonic
+ - [x] HyperVictor
+- [ ] Implement SuperComponents.
+ - [ ] SuperAHRS
+ - [ ] SuperAnalogPotentiometer
+ - [x] SuperCompressor
+ - [x] SuperDigitalInput
+ - [x] SuperDoubleSolenoid
+ - [x] SuperEncoder
+ - [x] SuperPDP
+ - [x] SuperSolenoid
+ - [x] SuperTalon
+ - [x] SuperUltrasonic
+ - [x] SuperVictor
+- [x] Improve Controller initialization.
+ - [x] Create JController class, for initializing Buttons along with a Controller.
+ - [x] Add Buttons for each POV and axis found for the Controller.
+- [ ] Add more flexibility and configuration options.
+- [x] Document everything properly.
+- [x] Do proper Exception handling.
+- [ ] Write proper documentation for this library.
+- [x] Blame mechanical.
+
+## Authors
+
+* **Francisco Rubio** - [pacoito123](https://github.com/pacoito123)
+
+## License
+
+This project is under the BSD License for WPILib code, see: [BSD_License_for_WPILib_code.txt](BSD_License_for_WPILib_code.txt).
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 006a0c0..f9c27a2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -21,6 +21,9 @@ repositories {
maven {
url "http://devsite.ctr-electronics.com/maven/release"
}
+ maven {
+ url "https://repo1.maven.org/maven2/"
+ }
}
dependencies {
@@ -46,6 +49,9 @@ dependencies {
//Phoenix dependencies.
compile group: 'com.ctre.phoenix', name: 'api-java', version: '5.14.1'
compile group: 'com.ctre.phoenix', name: 'wpiapi-java', version: '5.14.1'
+
+ //Kauai Labs dependencies.
+ compile group: 'com.kauailabs.navx.frc', name: 'navx-java', version: '3.1.367'
}
// Setting up my Jar File. In this case, adding all libraries into the main jar ('fat jar')
diff --git a/src/main/java/org/usfirst/lib6647/oi/ButtonHelper.java b/src/main/java/org/usfirst/lib6647/oi/ButtonHelper.java
index 421bf7b..f32f4d9 100644
--- a/src/main/java/org/usfirst/lib6647/oi/ButtonHelper.java
+++ b/src/main/java/org/usfirst/lib6647/oi/ButtonHelper.java
@@ -9,18 +9,25 @@
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
-import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.buttons.Button;
/**
- * Helper class for registering button input.
+ * Helper class for registering {@link Button} input.
*/
public class ButtonHelper {
+
+ /**
+ * HashMap where declared {@link JController joysticks} are stored.
+ */
public HashMap joysticks;
- String fileName;
/**
- * Constructor for the class.
+ * Location of the JSON file for {@link Button} nicknames.
+ */
+ private String fileName;
+
+ /**
+ * Helper class for registering {@link Button} input.
*
* @param fileName
*/
@@ -31,75 +38,79 @@ public ButtonHelper(String fileName) {
}
/**
- * Method for getting a button with a JSON name from a given joystick. Returns
- * null if no button is found.
+ * Method for getting a {@link Button} with a friendly name (declared in the
+ * JSON configuration) from a given {@link #joysticks joystick}. Returns null if
+ * no {@link Button} is found at that key.
*
- * @param joystick
+ * @param joystickName
* @param buttonName
- * @return button from the given joystick
+ * @return {@link Button}
*/
public Button oiButton(String joystickName, String buttonName) {
try {
+ // Create a new JSONParser and JSONObject with the given key.
JSONParser parser = new JSONParser();
Reader file = new FileReader(fileName);
JSONObject jsonJoystick = (JSONObject) ((JSONObject) parser.parse(file))
.get(joysticks.get(joystickName).getName());
+ // Create Button object and initialize it with values from the JSONObject.
Button button = joysticks.get(joystickName).buttons.get(jsonJoystick.get(buttonName).toString());
+ // Clear JSONObject and JSONParser after use, and close Reader. Not sure if it
+ // does anything, but it might free some unused memory.
jsonJoystick.clear();
file.close();
parser.reset();
+ // Finally, return Button object from the friendly name.
return button;
} catch (IOException e) {
- DriverStation.reportError("[!] OIBUTTON " + buttonName + " IO ERROR: " + e.getMessage(), false);
System.out.println("[!] OIBUTTON " + buttonName + " IO ERROR: " + e.getMessage());
- System.exit(1);
} catch (ParseException e) {
- DriverStation.reportError("[!] OIBUTTON " + buttonName + " PARSE ERROR: " + e.getMessage(), false);
System.out.println("[!] OIBUTTON " + buttonName + " PARSE ERROR: " + e.getMessage());
- System.exit(1);
} catch (Exception e) {
- DriverStation.reportError("[!] OIBUTTON " + buttonName + " ERROR: " + e.getMessage(), false);
System.out.println("[!] OIBUTTON " + buttonName + " ERROR: " + e.getMessage());
- System.exit(1);
}
return null;
}
/**
- * Method for getting a button from a given joystick.
+ * Method for getting a {@link Button} from a given {@link JController#joysticks
+ * joystick}.
*
* @param joystickName
* @param button
- * @return button from the given joystick
+ * @return button from the given {@link JController#joysticks joystick}
*/
public Button oiButton(String joystickName, int button) {
return joysticks.get(joystickName).buttons.get("Button" + button);
}
/**
- * Method for getting an axisButton from a given joystick.
+ * Method for getting a {@link Button} from an axisButton or dPadButton, from a
+ * given {@link JController#joysticks joystick}.
*
* @param joystickName
* @param type
* @param axis
- * @return axisButton from the given joystick, for the given axis
+ * @return {@link Button} from the given {@link JController#joysticks joystick},
+ * for the given axis or dPad
*/
public Button oiButton(String joystickName, String type, int axis) {
return joysticks.get(joystickName).buttons.get(type + axis);
}
/**
- * Method for getting an axisButton from a given joystick, at a specific angle.
+ * Method for getting a {@link Button} from an axisButton or dPadButton, from a
+ * given {@link JController#joysticks joystick}, at a specific angle.
*
* @param joystickName
* @param type
* @param axis
* @param angle
- * @return axisButton from the given joystick, for the given axis, for the given
- * angle
+ * @return {@link Button} from the given {@link JController#joysticks joystick},
+ * for the given axis or dPad, for the given angle or value
*/
public Button oiButton(String joystickName, String type, int axis, int angle) {
return joysticks.get(joystickName).buttons.get(type + axis + "_" + angle);
diff --git a/src/main/java/org/usfirst/lib6647/oi/JController.java b/src/main/java/org/usfirst/lib6647/oi/JController.java
index 0da4a14..441bb14 100644
--- a/src/main/java/org/usfirst/lib6647/oi/JController.java
+++ b/src/main/java/org/usfirst/lib6647/oi/JController.java
@@ -8,28 +8,39 @@
import edu.wpi.first.wpilibj.buttons.JoystickButton;
/**
- * Joystick wrapper for initializing buttons.
+ * Wrapper for the {@link Joystick} class for easy {@link Button}
+ * initialization, and more.
*/
public class JController extends Joystick {
+ /**
+ * HashMap storing the {@link JController}'s {@link Button Buttons}.
+ */
public HashMap buttons = new HashMap();
+
+ /**
+ * Left or right axis of the {@link JController} (assuming it's a gamepad).
+ */
private int leftAxis = 1, rightAxis = 5;
/**
- * Constructor for the controller.
+ * Constructor for {@link JController}.
*
- * Initializes each and every button from the joystick found at the given port.
- * Also initializes buttons for certain angles for each of the axis buttons.
+ * Initializes each and every {@link Button} from the {@link Joystick} found at
+ * the given port. Also initializes {@link Button Buttons} for each of the axes
+ * and POVs.
*
* @param port
*/
public JController(int port) {
super(port);
+ // Button initialization. Starting at 1.
for (int i = 1; i <= this.getButtonCount(); i++) {
buttons.put("Button" + i, new JoystickButton(this, i));
}
+ // dPadButton initialization. Starting at 0.
for (int i = 0; i < this.getPOVCount(); i++) {
buttons.put("dPad" + i, buttonFromPOV(this, i));
for (int j = 0; j <= 315; j += 45) {
@@ -37,17 +48,19 @@ public JController(int port) {
}
}
+ // axisButton initialization. Starting at 0.
for (int i = 0; i < this.getAxisCount(); i++) {
+ buttons.put("Stick" + i, buttonFromAxis(this, i));
buttons.put("Stick" + i + "_1", buttonFromAxisPositive(this, i));
buttons.put("Stick" + i + "_-1", buttonFromAxisNegative(this, i));
}
}
/**
- * Method to set left and right axis.
+ * Method to set {@link #leftAxis} and {@link #rightAxis}.
*
- * @param leftAxis
- * @param rightAxis
+ * @param {@link #leftAxis}
+ * @param {@link #rightAxis}
*/
public void setLeftRightAxis(int leftAxis, int rightAxis) {
this.leftAxis = leftAxis;
@@ -55,29 +68,29 @@ public void setLeftRightAxis(int leftAxis, int rightAxis) {
}
/**
- * Method to get left-most Stick raw value.
+ * Method to get {@link #leftAxis} raw value.
*
- * @return leftAxis
+ * @return {@link #leftAxis}
*/
public double getLeftAxis() {
return getRawAxis(leftAxis);
}
/**
- * Method to get right-most Stick raw value.
+ * Method to get {@link #rightAxis} raw value.
*
- * @return rightAxis
+ * @return {@link #rightAxis}
*/
public double getRightAxis() {
return getRawAxis(rightAxis);
}
/**
- * Method for getting a pov button at any angle.
+ * Method for getting a dPadButton input for any angle.
*
* @param controller
* @param pov
- * @return axisButton
+ * @return dPadButton
*/
private Button buttonFromPOV(GenericHID controller, int pov) {
return new Button() {
@@ -89,7 +102,7 @@ public boolean get() {
}
/**
- * Method for getting a pov button at a specific angle.
+ * Method for getting a dPadButton input for a specific angle.
*
* @param controller
* @param pov
@@ -106,7 +119,26 @@ public boolean get() {
}
/**
- * Method for getting a negative input from an axis.
+ * Method for getting an axisButton input for any value, with 0.15 as tolerance
+ * (so as to avoid accidental input due to improper {@link JController}
+ * calibration).
+ *
+ * @param controller
+ * @param axis
+ * @return axisButton
+ */
+ private Button buttonFromAxis(GenericHID controller, int axis) {
+ return new Button() {
+ @Override
+ public boolean get() {
+ return Math.abs(controller.getRawAxis(axis)) < 0.30;
+ }
+ };
+ }
+
+ /**
+ * Method for getting a negative axisButton input, with 0.15 as tolerance (to
+ * avoid accidental input due to improper {@link JController} calibration).
*
* @param controller
* @param axis
@@ -116,13 +148,14 @@ private Button buttonFromAxisNegative(GenericHID controller, int axis) {
return new Button() {
@Override
public boolean get() {
- return controller.getRawAxis(axis) < -0.15;
+ return controller.getRawAxis(axis) < -0.30;
}
};
}
/**
- * Method for getting a positive input from an axis.
+ * Method for getting a positive axisButton input, with 0.15 as tolerance (to
+ * avoid accidental input due to improper {@link JController} calibration).
*
* @param controller
* @param axis
@@ -132,7 +165,7 @@ private Button buttonFromAxisPositive(GenericHID controller, int axis) {
return new Button() {
@Override
public boolean get() {
- return controller.getRawAxis(axis) > 0.15;
+ return controller.getRawAxis(axis) > 0.30;
}
};
}
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/PIDSuperSubsystem.java b/src/main/java/org/usfirst/lib6647/subsystem/PIDSuperSubsystem.java
index e39dd98..dbf2f1b 100644
--- a/src/main/java/org/usfirst/lib6647/subsystem/PIDSuperSubsystem.java
+++ b/src/main/java/org/usfirst/lib6647/subsystem/PIDSuperSubsystem.java
@@ -6,23 +6,29 @@
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
-import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.command.PIDSubsystem;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
/**
- * Class to allow usage of JSON files for PIDSubsystem creation.
+ * Abstract class to allow usage of {@link #robotMap JSON files} for
+ * {@link PIDSubsystem} creation, with additional PID initialization.
*/
public abstract class PIDSuperSubsystem extends PIDSubsystem {
+ /**
+ * Bread and butter of {@link PIDSuperSubsystem}.
+ */
protected JSONObject robotMap;
protected float p = 0.0f, i = 0.0f, d = 0.0f;
+ protected double pidOutput;
/**
- * Constructor for the class.
+ * Constructor for {@link PIDSuperSubsystem}. Initializes the
+ * {@link PIDSubsystem} with 0.0f, 0.0f, and 0.0f as PID values, then replaces
+ * them with the values declared in {@link #robotMap}
*
- * @param name
- * @param fileName (of JSON)
+ * @param name (of the {@link PIDSubsystem})
+ * @param fileName (to {@link #robotMap JSON file})
*/
public PIDSuperSubsystem(String name, String fileName) {
super(name, 0.0f, 0.0f, 0.0f);
@@ -33,9 +39,9 @@ public PIDSuperSubsystem(String name, String fileName) {
}
/**
- * Method to initialize JSON at the given path.
+ * Method to initialize {@link #robotMap} at the given path.
*
- * @param fileName
+ * @param fileName (to {@link #robotMap JSON file})
*/
private void initJSON(String fileName) {
try {
@@ -44,25 +50,27 @@ private void initJSON(String fileName) {
robotMap = (JSONObject) parser.parse(file);
file.close();
} catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + getName().toUpperCase() + "' JSON INIT ERROR: " + e.getMessage(), false);
System.out.println("[!] SUBSYSTEM '" + getName().toUpperCase() + "' JSON INIT ERROR: " + e.getMessage());
System.exit(1);
}
}
/**
- * Method to initialize subsystem PID values and configuration.
+ * Method to initialize and set {@link PIDSuperSubsystem}'s PID values and
+ * configuration.
*/
private void initPID() {
try {
+ // Create a JSONObject out of the 'pid' key.
JSONObject pid = (JSONObject) ((JSONObject) ((JSONObject) robotMap.get("subsystems")).get(getName()))
.get("pid");
+ // Update current PID values.
p = Float.parseFloat(pid.get("p").toString());
i = Float.parseFloat(pid.get("i").toString());
d = Float.parseFloat(pid.get("d").toString());
+ // Update PIDSubsystem PID values and configuration.
getPIDController().setPID(p, i, d);
setInputRange(Double.parseDouble(pid.get("inputMin").toString()),
Double.parseDouble(pid.get("inputMax").toString()));
@@ -71,29 +79,30 @@ private void initPID() {
setAbsoluteTolerance(Double.parseDouble(pid.get("absoluteTolerance").toString()));
getPIDController().setContinuous(Boolean.parseBoolean(pid.get("continuous").toString()));
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
pid.clear();
} catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + getName().toUpperCase() + "' PID INIT ERROR: " + e.getMessage(), false);
System.out.println("[!] SUBSYSTEM '" + getName().toUpperCase() + "' PID INIT ERROR: " + e.getMessage());
System.exit(1);
}
}
/**
- * Method to clear JSONObject.
+ * Method to clear {@link #robotMap}.
*/
public void finishedJSONInit() {
robotMap.clear();
}
/**
- * Method to output PID values to the SmartDashboard.
+ * Method to output {@link #p}, {@link #i}, and {@link #d} values from the
+ * {@link PIDSuperSubsystem} to the {@link SmartDashboard}.
*
* @param subsystemName
- * @param p
- * @param i
- * @param d
+ * @param {@link #p}
+ * @param {@link #i}
+ * @param {@link #d}
*/
private void outputPIDValues(String subsystemName, float p, float i, float d) {
SmartDashboard.putString(subsystemName + "P", p + "");
@@ -102,7 +111,8 @@ private void outputPIDValues(String subsystemName, float p, float i, float d) {
}
/**
- * Method to update PID values from the SmartDashboard.
+ * Method to update {@link #p}, {@link #i}, and {@link #d} values as float from
+ * the {@link SmartDashboard}.
*/
public void updatePIDValues() {
p = Float.parseFloat(SmartDashboard.getString(getName() + "P", p + ""));
@@ -111,4 +121,14 @@ public void updatePIDValues() {
getPIDController().setPID(p, i, d);
}
+
+ /**
+ * Method to return {@link #pidOutput}, must be updated in a PID loop in order
+ * to be useful.
+ *
+ * @return pidOutput
+ */
+ public double getPIDOutput() {
+ return pidOutput;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/SuperSubsystem.java b/src/main/java/org/usfirst/lib6647/subsystem/SuperSubsystem.java
index ee90f3a..b1bdc4b 100644
--- a/src/main/java/org/usfirst/lib6647/subsystem/SuperSubsystem.java
+++ b/src/main/java/org/usfirst/lib6647/subsystem/SuperSubsystem.java
@@ -6,21 +6,24 @@
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
-import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.command.Subsystem;
/**
- * Class to allow usage of JSON files for Subsystem creation.
+ * Abstract class to allow usage of {@link #robotMap JSON files} for
+ * {@link Subsystem} creation.
*/
public abstract class SuperSubsystem extends Subsystem {
+ /**
+ * Bread and butter of {@link SuperSubsystem}.
+ */
protected JSONObject robotMap;
/**
- * Constructor for the class.
+ * Constructor for {@link SuperSubsystem}.
*
- * @param name
- * @param fileName (of JSON)
+ * @param name (of the {@link Subsystem})
+ * @param fileName (to {@link #robotMap JSON file})
*/
public SuperSubsystem(String name, String fileName) {
super(name);
@@ -29,9 +32,9 @@ public SuperSubsystem(String name, String fileName) {
}
/**
- * Method to initialize JSON at the given path.
+ * Method to initialize {@link #robotMap} at the given path.
*
- * @param fileName
+ * @param fileName (to {@link #robotMap JSON file})
*/
private void initJSON(String fileName) {
try {
@@ -40,15 +43,13 @@ private void initJSON(String fileName) {
robotMap = (JSONObject) parser.parse(file);
file.close();
} catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + getName().toUpperCase() + "' JSON INIT ERROR: " + e.getMessage(), false);
System.out.println("[!] SUBSYSTEM '" + getName().toUpperCase() + "' JSON INIT ERROR: " + e.getMessage());
System.exit(1);
}
}
/**
- * Method to clear JSONObject.
+ * Method to clear {@link #robotMap}.
*/
public void finishedJSONInit() {
robotMap.clear();
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperCompressor.java b/src/main/java/org/usfirst/lib6647/subsystem/components/SuperCompressor.java
deleted file mode 100644
index 2a473e7..0000000
--- a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperCompressor.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.usfirst.lib6647.subsystem.components;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-
-import edu.wpi.first.wpilibj.Compressor;
-import edu.wpi.first.wpilibj.DriverStation;
-
-/**
- * Interface to allow Compressor initialization via JSON file. Subsystem needs
- * to extend SuperSubsystem.
- */
-public interface SuperCompressor {
- /**
- * HashMap storing the SuperSubsystem's Compressors.
- */
- public HashMap compressors = new HashMap();
-
- /**
- * Method to initialize Compressors declared in JSON file, and add them to the
- * HashMap using its name as its key.
- *
- * @param robotMap
- * @param subsystemName
- */
- default void initCompressors(JSONObject robotMap, String subsystemName) {
- try {
- JSONArray compressorArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
- .get(subsystemName)).get("compressors");
- Arrays.stream(compressorArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
- try {
- Compressor compressor = new Compressor(Integer.parseInt(json.get("module").toString()));
- compressors.put(json.get("name").toString(), compressor);
- } catch (Exception e) {
- DriverStation.reportError("[!] SUBSYSTEM '" + subsystemName.toUpperCase()
- + "' COMPRESSOR INIT ERROR: " + e.getMessage(), false);
- System.out.println("[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' COMPRESSOR INIT ERROR: "
- + e.getMessage());
- System.exit(1);
- } finally {
- json.clear();
- }
- });
- compressorArray.clear();
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' COMPRESSOR INIT ERROR: " + e.getMessage(),
- false);
- System.out.println(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' COMPRESSOR INIT ERROR: " + e.getMessage());
- System.exit(1);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperDigitalInput.java b/src/main/java/org/usfirst/lib6647/subsystem/components/SuperDigitalInput.java
deleted file mode 100644
index f7906e7..0000000
--- a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperDigitalInput.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.usfirst.lib6647.subsystem.components;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-
-import edu.wpi.first.wpilibj.DigitalInput;
-import edu.wpi.first.wpilibj.DriverStation;
-
-/**
- * Interface to allow DigitalInput initialization via JSON file. Subsystem needs
- * to extend SuperSubsystem.
- */
-public interface SuperDigitalInput {
- /**
- * HashMap storing the SuperSubsystem's DigitalInputs.
- */
- public HashMap digitalInputs = new HashMap();
-
- /**
- * Method to initialize DigitalInputs declared in JSON file, and add them to the
- * HashMap using its name as its key.
- *
- * @param robotMap
- * @param subsystemName
- */
- default void initDigitalInputs(JSONObject robotMap, String subsystemName) {
- try {
- JSONArray digitalInputArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
- .get(subsystemName)).get("digitalInputs");
- Arrays.stream(digitalInputArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
- try {
- DigitalInput digitalInput = new DigitalInput(Integer.parseInt(json.get("channel").toString()));
- digitalInputs.put(json.get("name").toString(), digitalInput);
- } catch (Exception e) {
- DriverStation.reportError("[!] SUBSYSTEM '" + subsystemName.toUpperCase()
- + "' DIGITAL INPUT INIT ERROR: " + e.getMessage(), false);
- System.out.println("[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' DIGITAL INPUT INIT ERROR: "
- + e.getMessage());
- System.exit(1);
- } finally {
- json.clear();
- }
- });
- digitalInputArray.clear();
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' DIGITAL INPUT INIT ERROR: " + e.getMessage(),
- false);
- System.out.println(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' DIGITAL INPUT INIT ERROR: " + e.getMessage());
- System.exit(1);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperEncoder.java b/src/main/java/org/usfirst/lib6647/subsystem/components/SuperEncoder.java
deleted file mode 100644
index a9ef080..0000000
--- a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperEncoder.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.usfirst.lib6647.subsystem.components;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-
-import edu.wpi.first.wpilibj.CounterBase.EncodingType;
-import edu.wpi.first.wpilibj.DriverStation;
-import edu.wpi.first.wpilibj.Encoder;
-
-/**
- * Interface to allow Encoder initialization via JSON file. Subsystem needs to
- * extend SuperSubsystem.
- */
-public interface SuperEncoder {
- /**
- * HashMap storing the SuperSubsystem's Encoders.
- */
- public HashMap encoders = new HashMap();
-
- /**
- * Method to initialize Encoders declared in JSON file, and add them to the
- * HashMap using its name as its key.
- *
- * @param robotMap
- * @param subsystemName
- */
- default void initEncoders(JSONObject robotMap, String subsystemName) {
- try {
- JSONArray encoderArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
- .get(subsystemName)).get("encoders");
- Arrays.stream(encoderArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
- try {
- Encoder encoder = new Encoder(Integer.parseInt(json.get("channelA").toString()),
- Integer.parseInt(json.get("channelB").toString()),
- Boolean.parseBoolean(json.get("reverse").toString()),
- getEncodingType(json.get("encodingType").toString()));
- encoder.reset();
-
- encoders.put(json.get("name").toString(), encoder);
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' ENCODER INIT ERROR: " + e.getMessage(),
- false);
- System.out.println("[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' ENCODER INIT ERROR: "
- + e.getMessage());
- System.exit(1);
- } finally {
- json.clear();
- }
- });
- encoderArray.clear();
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' ENCODER INIT ERROR: " + e.getMessage(), false);
- System.out.println(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' ENCODER INIT ERROR: " + e.getMessage());
- System.exit(1);
- }
- }
-
- default EncodingType getEncodingType(String encodingType) {
- switch (encodingType) {
- case "k1X":
- return EncodingType.k1X;
- case "k2X":
- return EncodingType.k2X;
- case "k4X":
- return EncodingType.k4X;
- default:
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperPDP.java b/src/main/java/org/usfirst/lib6647/subsystem/components/SuperPDP.java
deleted file mode 100644
index 5f50f91..0000000
--- a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperPDP.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.usfirst.lib6647.subsystem.components;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-
-import edu.wpi.first.wpilibj.DriverStation;
-import edu.wpi.first.wpilibj.PowerDistributionPanel;
-
-/**
- * Interface to allow PowerDistributionPanel initialization via JSON file.
- * Subsystem needs to extend SuperSubsystem.
- */
-public interface SuperPDP {
- /**
- * HashMap storing the SuperSubsystem's PowerDistributionPanel objects.
- */
- public HashMap PDPs = new HashMap();
-
- /**
- * Method to initialize PDPs declared in JSON file, and add them to the HashMap
- * using its name as its key.
- *
- * @param robotMap
- * @param subsystemName
- */
- default void initPDPs(JSONObject robotMap, String subsystemName) {
- try {
- JSONArray PDPArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems")).get(subsystemName))
- .get("PDPs");
- Arrays.stream(PDPArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
- try {
- PowerDistributionPanel pdp = new PowerDistributionPanel(
- Integer.parseInt(json.get("module").toString()));
- PDPs.put(json.get("name").toString(), pdp);
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' PDP INIT ERROR: " + e.getMessage(),
- false);
- System.out.println(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' PDP INIT ERROR: " + e.getMessage());
- System.exit(1);
- } finally {
- json.clear();
- }
- });
- PDPArray.clear();
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' PDP INIT ERROR: " + e.getMessage(), false);
- System.out.println("[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' PDP INIT ERROR: " + e.getMessage());
- System.exit(1);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperSolenoid.java b/src/main/java/org/usfirst/lib6647/subsystem/components/SuperSolenoid.java
deleted file mode 100644
index 8a2c637..0000000
--- a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperSolenoid.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.usfirst.lib6647.subsystem.components;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-
-import edu.wpi.first.wpilibj.DriverStation;
-import edu.wpi.first.wpilibj.Solenoid;
-
-/**
- * Interface to allow Solenoid initialization via JSON file. Subsystem needs to
- * extend SuperSubsystem.
- */
-public interface SuperSolenoid {
- /**
- * HashMap storing the SuperSubsystem's Solenoids.
- */
- public HashMap solenoids = new HashMap();
-
- /**
- * Method to initialize Solenoids declared in JSON file, and add them to the
- * HashMap using its name as its key.
- *
- * @param robotMap
- * @param subsystemName
- */
- default void initSolenoids(JSONObject robotMap, String subsystemName) {
- try {
- JSONArray solenoidArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
- .get(subsystemName)).get("solenoids");
- Arrays.stream(solenoidArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
- try {
- Solenoid solenoid = new Solenoid(Integer.parseInt(json.get("channel").toString()));
-
- if (json.containsKey("initialValue"))
- solenoid.set(Boolean.parseBoolean(json.get("initialValue").toString()));
-
- solenoids.put(json.get("name").toString(), solenoid);
- } catch (Exception e) {
- DriverStation.reportError("[!] SUBSYSTEM '" + subsystemName.toUpperCase()
- + "' SOLENOID INIT ERROR: " + e.getMessage(), false);
- System.out.println("[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' SOLENOID INIT ERROR: "
- + e.getMessage());
- System.exit(1);
- } finally {
- json.clear();
- }
- });
- solenoidArray.clear();
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' SOLENOID INIT ERROR: " + e.getMessage(),
- false);
- System.out.println(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' SOLENOID INIT ERROR: " + e.getMessage());
- System.exit(1);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperTalon.java b/src/main/java/org/usfirst/lib6647/subsystem/components/SuperTalon.java
deleted file mode 100644
index ca37d64..0000000
--- a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperTalon.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.usfirst.lib6647.subsystem.components;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.usfirst.lib6647.util.MotorUtils;
-
-import edu.wpi.first.wpilibj.DriverStation;
-
-/**
- * Interface to allow Talon initialization via JSON file. Subsystem needs to
- * extend SuperSubsystem.
- */
-public interface SuperTalon extends MotorUtils {
- /**
- * HashMap storing the SuperSubsystem's Talons.
- */
- public HashMap talons = new HashMap();
-
- /**
- * Method to initialize Talons declared in JSON file, and add them to the
- * HashMap using its name as its key. ALWAYS declare and initialize masters
- * before followers in the JSON file.
- *
- * @param robotMap
- * @param subsystemName
- */
- default void initTalons(JSONObject robotMap, String subsystemName) {
- try {
- JSONArray talonArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
- .get(subsystemName)).get("talons");
- Arrays.stream(talonArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
- try {
- WPI_TalonSRX talon = new WPI_TalonSRX(Integer.parseInt(json.get("port").toString()));
-
- if (json.containsKey("inverted"))
- setInverted(json, talon);
-
- if (json.containsKey("neutralMode"))
- setNeutralMode(json, talon);
-
- if (json.containsKey("loopRamp"))
- setLoopRamp(json, talon);
-
- if (json.containsKey("sensor"))
- setSensors(json, talon);
-
- if (json.containsKey("pid"))
- setPIDValues(json, talon);
-
- talons.put(json.get("name").toString(), talon);
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' TALON INIT ERROR: " + e.getMessage(),
- false);
- System.out.println(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' TALON INIT ERROR: " + e.getMessage());
- System.exit(1);
- } finally {
- json.clear();
- }
- });
- talonArray.clear();
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' TALON INIT ERROR: " + e.getMessage(), false);
- System.out
- .println("[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' TALON INIT ERROR: " + e.getMessage());
- System.exit(1);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperUltrasonic.java b/src/main/java/org/usfirst/lib6647/subsystem/components/SuperUltrasonic.java
deleted file mode 100644
index a80ed62..0000000
--- a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperUltrasonic.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.usfirst.lib6647.subsystem.components;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-
-import edu.wpi.first.wpilibj.DriverStation;
-import edu.wpi.first.wpilibj.Ultrasonic;
-
-/**
- * Interface to allow Ultrasonic initialization via JSON file. Subsystem needs
- * to extend SuperSubsystem.
- */
-public interface SuperUltrasonic {
- /**
- * HashMap storing the SuperSubsystem's Ultrasonics.
- */
- public HashMap ultrasonics = new HashMap();
-
- /**
- * Method to initialize Ultrasonics declared in JSON file, and add them to the
- * HashMap using its name as its key.
- *
- * @param robotMap
- * @param subsystemName
- */
- default void initUltrasonics(JSONObject robotMap, String subsystemName) {
- try {
- JSONArray ultrasonicArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
- .get(subsystemName)).get("ultrasonics");
- Arrays.stream(ultrasonicArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
- try {
- Ultrasonic ultrasonic = new Ultrasonic(Integer.parseInt(json.get("pingChannel").toString()),
- Integer.parseInt(json.get("echoChannel").toString()));
- ultrasonics.put(json.get("name").toString(), ultrasonic);
- } catch (Exception e) {
- DriverStation.reportError("[!] SUBSYSTEM '" + subsystemName.toUpperCase()
- + "' ULTRASONIC INIT ERROR: " + e.getMessage(), false);
- System.out.println("[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' ULTRASONIC INIT ERROR: "
- + e.getMessage());
- System.exit(1);
- } finally {
- json.clear();
- }
- });
- ultrasonicArray.clear();
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' ULTRASONIC INIT ERROR: " + e.getMessage(),
- false);
- System.out.println(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' ULTRASONIC INIT ERROR: " + e.getMessage());
- System.exit(1);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperVictor.java b/src/main/java/org/usfirst/lib6647/subsystem/components/SuperVictor.java
deleted file mode 100644
index 05a5d0c..0000000
--- a/src/main/java/org/usfirst/lib6647/subsystem/components/SuperVictor.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.usfirst.lib6647.subsystem.components;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import com.ctre.phoenix.motorcontrol.can.WPI_VictorSPX;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.usfirst.lib6647.util.MotorUtils;
-
-import edu.wpi.first.wpilibj.DriverStation;
-
-/**
- * Interface to allow Victor initialization via JSON file. Subsystem needs to
- * extend SuperSubsystem.
- */
-public interface SuperVictor extends MotorUtils {
- /**
- * HashMap storing the SuperSubsystem's Victors.
- */
- public HashMap victors = new HashMap();
-
- /**
- * Method to initialize Victors declared in JSON file, and add them to the
- * HashMap using its name as its key. ALWAYS declare and initialize masters
- * before followers!
- *
- * @param robotMap
- * @param subsystemName
- */
- default void initVictors(JSONObject robotMap, String subsystemName) {
- try {
- JSONArray victorArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
- .get(subsystemName)).get("victors");
- Arrays.stream(victorArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
- try {
- WPI_VictorSPX victor = new WPI_VictorSPX(Integer.parseInt(json.get("port").toString()));
-
- if (json.containsKey("inverted"))
- setInverted(json, victor);
-
- if (json.containsKey("neutralMode"))
- setNeutralMode(json, victor);
-
- if (json.containsKey("loopRamp"))
- setLoopRamp(json, victor);
-
- victors.put(json.get("name").toString(), victor);
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' VICTOR INIT ERROR: " + e.getMessage(),
- false);
- System.out.println(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' VICTOR INIT ERROR: " + e.getMessage());
- System.exit(1);
- } finally {
- json.clear();
- }
- });
- victorArray.clear();
- } catch (Exception e) {
- DriverStation.reportError(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' VICTOR INIT ERROR: " + e.getMessage(), false);
- System.out.println(
- "[!] SUBSYSTEM '" + subsystemName.toUpperCase() + "' VICTOR INIT ERROR: " + e.getMessage());
- System.exit(1);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperDoubleSolenoid.java b/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperDoubleSolenoid.java
new file mode 100644
index 0000000..eab1afb
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperDoubleSolenoid.java
@@ -0,0 +1,50 @@
+package org.usfirst.lib6647.subsystem.hypercomponents;
+
+import edu.wpi.first.wpilibj.Solenoid;
+
+/**
+ * HyperComponent for a {@link Solenoid DoubleSolenoid}.
+ */
+public class HyperDoubleSolenoid {
+
+ /**
+ * {@link Solenoid Solenoids} for .
+ */
+ private Solenoid forward, reverse;
+
+ /**
+ * Wrapper for a {@link Solenoid DoubleSolenoid}.
+ *
+ * @param forwardChannel
+ * @param reverseChannel
+ */
+ public HyperDoubleSolenoid(int forwardChannel, int reverseChannel) {
+ forward = new Solenoid(forwardChannel);
+ reverse = new Solenoid(reverseChannel);
+ }
+
+ /**
+ * Set {@link Solenoid DoubleSolenoid} to a specific value.
+ *
+ * @param value
+ */
+ public void set(boolean value) {
+ forward.set(value);
+ reverse.set(!value);
+ }
+
+ /**
+ * Toggle {@link Solenoid DoubleSolenoid}.
+ */
+ public void toggle() {
+ set(!forward.get());
+ }
+
+ /**
+ * Stop any {@link Solenoid DoubleSolenoid} movement.
+ */
+ public void stop() {
+ forward.set(false);
+ reverse.set(false);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperSolenoid.java b/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperSolenoid.java
new file mode 100644
index 0000000..5078411
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperSolenoid.java
@@ -0,0 +1,25 @@
+package org.usfirst.lib6647.subsystem.hypercomponents;
+
+import edu.wpi.first.wpilibj.Solenoid;
+
+/**
+ * HyperComponent for {@link Solenoid}.
+ */
+public class HyperSolenoid extends Solenoid {
+
+ /**
+ * Wrapper for {@link Solenoid}.
+ *
+ * @param channel
+ */
+ public HyperSolenoid(int channel) {
+ super(channel);
+ }
+
+ /**
+ * Toggle {@link Solenoid}.
+ */
+ public void toggle() {
+ set(!get());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperTalon.java b/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperTalon.java
new file mode 100644
index 0000000..4a8e1e1
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperTalon.java
@@ -0,0 +1,94 @@
+package org.usfirst.lib6647.subsystem.hypercomponents;
+
+import com.ctre.phoenix.motorcontrol.ControlMode;
+import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX;
+
+/**
+ * HyperComponent for {@link WPI_TalonSRX}.
+ */
+public class HyperTalon extends WPI_TalonSRX {
+
+ /**
+ * Limits how fast the Talon can go as a percentage if using
+ * {@link #setTalonWithRamp(double)} or {@link #setTalon(double, boolean)} if
+ * true.
+ */
+ private double limiter = 1;
+
+ /**
+ * Wrapper for {@link WPI_TalonSRX}.
+ *
+ * @param port
+ */
+ public HyperTalon(int port) {
+ super(port);
+
+ configFactoryDefault();
+ }
+
+ /**
+ * Returns {@link #limiter} value for {@link WPI_TalonSRX} speed.
+ *
+ * @return
+ */
+ public double getLimiter() {
+ return limiter;
+ }
+
+ /**
+ * Sets {@link #limiter} for {@link WPI_TalonSRX} speed.
+ */
+ public void setLimiter(double limiter) {
+ this.limiter = limiter;
+ }
+
+ /**
+ * Raises {@link #limiter} by a given amount.
+ *
+ * @param amount
+ */
+ public void raiseLimiter(double amount) {
+ limiter += amount;
+ }
+
+ /**
+ * Sets {@link HyperTalon} to a given speed, in {@link ControlMode#PercentOutput
+ * PercentOutput}.
+ *
+ * @param speed
+ */
+ public void setTalon(double speed) {
+ setTalon(speed, false);
+ }
+
+ /**
+ * Sets {@link HyperTalon} to a given speed, in {@link ControlMode#PercentOutput
+ * PercentOutput}.
+ *
+ * @param speed
+ * @param limited
+ */
+ public void setTalon(double speed, boolean limited) {
+ if (speed >= limiter && limited)
+ super.set(ControlMode.PercentOutput, limiter);
+ else
+ super.set(ControlMode.PercentOutput, speed);
+ }
+
+ /**
+ * Sets {@link HyperTalon} to a given amount multiplied by {@link #limiter}, in
+ * {@link ControlMode#PercentOutput PercentOutput}.
+ *
+ * @param speed
+ */
+ public void setTalonWithRamp(double speed) {
+ super.set(ControlMode.PercentOutput, speed * limiter);
+ }
+
+ /**
+ * Stops {@link HyperTalon} dead in its tracks.
+ */
+ public void stopTalon() {
+ setTalon(0, false);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperVictor.java b/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperVictor.java
new file mode 100644
index 0000000..f4c4911
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/hypercomponents/HyperVictor.java
@@ -0,0 +1,94 @@
+package org.usfirst.lib6647.subsystem.hypercomponents;
+
+import com.ctre.phoenix.motorcontrol.ControlMode;
+import com.ctre.phoenix.motorcontrol.can.WPI_VictorSPX;
+
+/**
+ * HyperComponent for {@link WPI_VictorSPX}.
+ */
+public class HyperVictor extends WPI_VictorSPX {
+
+ /**
+ * Limits how fast the Victor can go as a percentage if using
+ * {@link #setVictorWithRamp(double)} or {@link #setVictor(double, boolean)} if
+ * true.
+ */
+ private double limiter = 1;
+
+ /**
+ * Wrapper for {@link WPI_VictorSPX}.
+ *
+ * @param port
+ */
+ public HyperVictor(int port) {
+ super(port);
+
+ configFactoryDefault();
+ }
+
+ /**
+ * Returns {@link #limiter} value for Victor speed.
+ *
+ * @return
+ */
+ public double getLimiter() {
+ return limiter;
+ }
+
+ /**
+ * Sets {@link #limiter limiter} for Victor speed.
+ */
+ public void setLimiter(double limiter) {
+ this.limiter = limiter;
+ }
+
+ /**
+ * Raises {@link #limiter} by a given amount.
+ *
+ * @param amount
+ */
+ public void raiseLimiter(double amount) {
+ limiter += amount;
+ }
+
+ /**
+ * Sets {@link HyperVictor} to a given speed, in
+ * {@link ControlMode#PercentOutput PercentOutput}.
+ *
+ * @param speed
+ */
+ public void setVictor(double speed) {
+ setVictor(speed, false);
+ }
+
+ /**
+ * Sets {@link HyperVictor} to a given speed, in
+ * {@link ControlMode#PercentOutput PercentOutput}.
+ *
+ * @param speed
+ * @param limited
+ */
+ public void setVictor(double speed, boolean limited) {
+ if (speed >= limiter && limited)
+ super.set(ControlMode.PercentOutput, limiter);
+ else
+ super.set(ControlMode.PercentOutput, speed);
+ }
+
+ /**
+ * Sets {@link HyperVictor} to a given amount multiplied by {@link #limiter}, in
+ * {@link ControlMode#PercentOutput PercentOutput}.
+ *
+ * @param speed
+ */
+ public void setVictorWithRamp(double speed) {
+ super.set(ControlMode.PercentOutput, speed * limiter);
+ }
+
+ /**
+ * Stops {@link HyperVictor} dead in its tracks.
+ */
+ public void stopVictor() {
+ setVictor(0, false);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperCompressor.java b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperCompressor.java
new file mode 100644
index 0000000..1cfa659
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperCompressor.java
@@ -0,0 +1,80 @@
+package org.usfirst.lib6647.subsystem.supercomponents;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.usfirst.lib6647.subsystem.PIDSuperSubsystem;
+import org.usfirst.lib6647.subsystem.SuperSubsystem;
+import org.usfirst.lib6647.util.ComponentInitException;
+
+import edu.wpi.first.wpilibj.Compressor;
+
+/**
+ * Interface to allow {@link Compressor} initialization via JSON. Subsystems
+ * declared need to extend {@link SuperSubsystem} or {@link PIDSuperSubsystem}
+ * and implement this interface in order to initialize {@link Compressor
+ * Compressors} declared in {@link SuperSubsystem#robotMap robotMap}.
+ */
+public interface SuperCompressor {
+ /**
+ * HashMap storing the {@link SuperSubsystem}'s {@link Compressor Compressors}.
+ */
+ public HashMap compressors = new HashMap();
+
+ /**
+ * Method to initialize {@link Compressor Compressors} declared in the
+ * {@link SuperSubsystem#robotMap robotMap} JSON file, and add them to the
+ * {@link #compressors} HashMap using its declared name as its key.
+ *
+ * @param {@link SuperSubsystem#robotMap}
+ * @param {@link SuperSubsystem#getName}
+ */
+ default void initCompressors(JSONObject robotMap, String subsystemName) {
+ // Create a JSONArray out of the declared objects.
+ JSONArray compressorArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
+ .get(subsystemName)).get("compressors");
+ // Create a stream to cast each entry in the JSONArray into a JSONObject, in
+ // order to configure it using the values declared in the robotMap file.
+ Arrays.stream(compressorArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
+ try {
+ if (json.containsKey("name") && json.containsKey("module")) {
+
+ Compressor compressor;
+ try {
+ // Try to initialize an object from an index in the JSONArray.
+ compressor = new Compressor(Integer.parseInt(json.get("module").toString()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format(
+ "[!] INVALID OR EMPTY MODULE VALUE FOR COMPRESSOR '%1$s' IN SUBSYSTEM '%2$s'",
+ json.get("name").toString(), subsystemName));
+ }
+
+ // Put object in HashMap with its declared name as key after initialization and
+ // configuration.
+ compressors.put(json.get("name").toString(), compressor);
+ }
+ } catch (ComponentInitException e) {
+ System.out.println(e.getMessage());
+ } finally {
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
+ json.clear();
+ }
+ });
+ // Clear JSONArray after use, not sure if it does anything, but it might free
+ // some unused memory.
+ compressorArray.clear();
+ }
+
+ /**
+ * Gets specified {@link Compressor}.
+ *
+ * @return {@link Compressor}
+ * @param compressorName
+ */
+ default Compressor getCompressor(String compressorName) {
+ return compressors.get(compressorName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperDigitalInput.java b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperDigitalInput.java
new file mode 100644
index 0000000..7a502ea
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperDigitalInput.java
@@ -0,0 +1,81 @@
+package org.usfirst.lib6647.subsystem.supercomponents;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.usfirst.lib6647.subsystem.PIDSuperSubsystem;
+import org.usfirst.lib6647.subsystem.SuperSubsystem;
+import org.usfirst.lib6647.util.ComponentInitException;
+
+import edu.wpi.first.wpilibj.DigitalInput;
+
+/**
+ * Interface to allow {@link DigitalInput} initialization via JSON. Subsystems
+ * declared need to extend {@link SuperSubsystem} or {@link PIDSuperSubsystem}
+ * and implement this interface in order to initialize {@link DigitalInput
+ * DigitalInputs} declared in {@link SuperSubsystem#robotMap robotMap}.
+ */
+public interface SuperDigitalInput {
+ /**
+ * HashMap storing the {@link SuperSubsystem}'s {@link DigitalInput
+ * DigitalInputs}.
+ */
+ public HashMap digitalInputs = new HashMap();
+
+ /**
+ * Method to initialize {@link DigitalInput DigitalInputs} declared in the
+ * {@link SuperSubsystem#robotMap robotMap} JSON file, and add them to the
+ * {@link #digitalInputs} HashMap using its declared name as its key.
+ *
+ * @param {@link SuperSubsystem#robotMap}
+ * @param {@link SuperSubsystem#getName}
+ */
+ default void initDigitalInputs(JSONObject robotMap, String subsystemName) {
+ // Create a JSONArray out of the declared objects.
+ JSONArray digitalInputArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
+ .get(subsystemName)).get("digitalInputs");
+ // Create a stream to cast each entry in the JSONArray into a JSONObject, in
+ // order to configure it using the values declared in the robotMap file.
+ Arrays.stream(digitalInputArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
+ try {
+ if (json.containsKey("name") && json.containsKey("channel")) {
+
+ DigitalInput digitalInput;
+ try {
+ // Try to initialize an object from an index in the JSONArray.
+ digitalInput = new DigitalInput(Integer.parseInt(json.get("channel").toString()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format(
+ "[!] INVALID OR EMPTY CHANNEL VALUE FOR DIGITALINPUT '%1$s' IN SUBSYSTEM '%2$s'",
+ json.get("name").toString(), subsystemName));
+ }
+
+ // Put object in HashMap with its declared name as key after initialization and
+ // configuration.
+ digitalInputs.put(json.get("name").toString(), digitalInput);
+ }
+ } catch (ComponentInitException e) {
+ System.out.println(e.getMessage());
+ } finally {
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
+ json.clear();
+ }
+ });
+ // Clear JSONArray after use, not sure if it does anything, but it might free
+ // some unused memory.
+ digitalInputArray.clear();
+ }
+
+ /**
+ * Gets specified {@link DigitalInput}.
+ *
+ * @return {@link DigitalInput}
+ * @param digitalInputName
+ */
+ default DigitalInput getDigitalInput(String digitalInputName) {
+ return digitalInputs.get(digitalInputName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperDoubleSolenoid.java b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperDoubleSolenoid.java
new file mode 100644
index 0000000..ca444e4
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperDoubleSolenoid.java
@@ -0,0 +1,87 @@
+package org.usfirst.lib6647.subsystem.supercomponents;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.usfirst.lib6647.subsystem.PIDSuperSubsystem;
+import org.usfirst.lib6647.subsystem.SuperSubsystem;
+import org.usfirst.lib6647.subsystem.hypercomponents.HyperDoubleSolenoid;
+import org.usfirst.lib6647.util.ComponentInitException;
+
+/**
+ * Interface to allow {@link HyperDoubleSolenoid} initialization via JSON.
+ * Subsystems declared need to extend {@link SuperSubsystem} or
+ * {@link PIDSuperSubsystem} and implement this interface in order to initialize
+ * {@link HyperDoubleSolenoid HyperDoubleSolenoids} declared in
+ * {@link SuperSubsystem#robotMap robotMap}.
+ */
+public interface SuperDoubleSolenoid {
+ /**
+ * HashMap storing the {@link SuperSubsystem}'s {@link HyperDoubleSolenoid
+ * HyperDoubleSolenoids}.
+ */
+ public HashMap solenoids = new HashMap();
+
+ /**
+ * Method to initialize {@link HyperDoubleSolenoid HyperDoubleSolenoids}
+ * declared in the {@link SuperSubsystem#robotMap robotMap} JSON file, and add
+ * them to the {@link #solenoids} HashMap using its declared name as its key.
+ *
+ * @param {@link SuperSubsystem#robotMap}
+ * @param {@link SuperSubsystem#getName}
+ */
+ default void initSolenoids(JSONObject robotMap, String subsystemName) {
+ // Create a JSONArray out of the declared objects.
+ JSONArray solenoidArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
+ .get(subsystemName)).get("doubleSolenoids");
+ // Create a stream to cast each entry in the JSONArray into a JSONObject, in
+ // order to configure it using the values declared in the robotMap file.
+ Arrays.stream(solenoidArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
+ try {
+ if (json.containsKey("name") && json.containsKey("forwardChannel")
+ && json.containsKey("reverseChannel")) {
+
+ HyperDoubleSolenoid solenoid;
+ try {
+ // Try to initialize an object from an index in the JSONArray.
+ solenoid = new HyperDoubleSolenoid(Integer.parseInt(json.get("forwardChannel").toString()),
+ Integer.parseInt(json.get("reverseChannel").toString()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format(
+ "[!] INVALID OR EMPTY CHANNEL VALUE(S) FOR DOUBLESOLENOID '%1$s' IN SUBSYSTEM '%2$s'",
+ json.get("name").toString(), subsystemName));
+ }
+ solenoid.stop();
+
+ // Put object in HashMap with its declared name as key after initialization and
+ // configuration.
+ solenoids.put(json.get("name").toString(), solenoid);
+ } else {
+ System.out.println(String.format("[!] UNDECLARED OR EMPTY DOUBLESOLENOID ENTRY IN SUBSYSTEM '%s'",
+ subsystemName.toUpperCase()));
+ }
+ } catch (ComponentInitException e) {
+ System.out.println(e.getMessage());
+ } finally {
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
+ json.clear();
+ }
+ });
+ // Clear JSONArray after use, not sure if it does anything, but it might free
+ // some unused memory.
+ solenoidArray.clear();
+ }
+
+ /**
+ * Gets specified {@link HyperDoubleSolenoid}.
+ *
+ * @return {@link HyperDoubleSolenoid}
+ * @param solenoidName
+ */
+ default HyperDoubleSolenoid getSolenoid(String solenoidName) {
+ return solenoids.get(solenoidName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperEncoder.java b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperEncoder.java
new file mode 100644
index 0000000..4cfdb86
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperEncoder.java
@@ -0,0 +1,86 @@
+package org.usfirst.lib6647.subsystem.supercomponents;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.usfirst.lib6647.subsystem.PIDSuperSubsystem;
+import org.usfirst.lib6647.subsystem.SuperSubsystem;
+import org.usfirst.lib6647.util.ComponentInitException;
+import org.usfirst.lib6647.util.MotorUtils;
+
+import edu.wpi.first.wpilibj.Encoder;
+
+/**
+ * Interface to allow {@link Encoder} initialization via JSON. Subsystems
+ * declared need to extend {@link SuperSubsystem} or {@link PIDSuperSubsystem}
+ * and implement this interface in order to initialize {@link Encoder Encoders}
+ * declared in {@link SuperSubsystem#robotMap robotMap}.
+ */
+public interface SuperEncoder extends MotorUtils {
+ /**
+ * HashMap storing the {@link SuperSubsystem}'s {@link Encoder Encoders}.
+ */
+ public HashMap encoders = new HashMap();
+
+ /**
+ * Method to initialize {@link Encoder Encoders} declared in the
+ * {@link SuperSubsystem#robotMap robotMap} JSON file, and add them to the
+ * {@link #encoders} HashMap using its declared name as its key.
+ *
+ * @param {@link SuperSubsystem#robotMap}
+ * @param {@link SuperSubsystem#getName}
+ */
+ default void initEncoders(JSONObject robotMap, String subsystemName) {
+ // Create a JSONArray out of the declared objects.
+ JSONArray encoderArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems")).get(subsystemName))
+ .get("encoders");
+ // Create a stream to cast each entry in the JSONArray into a JSONObject, in
+ // order to configure it using the values declared in the robotMap file.
+ Arrays.stream(encoderArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
+ try {
+ if (json.containsKey("name") && json.containsKey("channelA") && json.containsKey("channelB")
+ && json.containsKey("reverse") && json.containsKey("encodingType")) {
+
+ Encoder encoder;
+ try {
+ // Try to initialize an object from an index in the JSONArray.
+ encoder = new Encoder(Integer.parseInt(json.get("channelA").toString()),
+ Integer.parseInt(json.get("channelB").toString()),
+ Boolean.parseBoolean(json.get("reverse").toString()),
+ getEncodingType(json.get("encodingType").toString()));
+ } catch (NullPointerException | NumberFormatException e) {
+ throw new ComponentInitException(
+ String.format("[!] INVALID OR EMPTY VALUE(S) FOR ENCODER '%1$s' IN SUBSYSTEM '%2$s'",
+ json.get("name").toString(), subsystemName));
+ }
+ encoder.reset();
+
+ // Put object in HashMap with its declared name as key after initialization and
+ // configuration.
+ encoders.put(json.get("name").toString(), encoder);
+ }
+ } catch (ComponentInitException e) {
+ System.out.println(e.getMessage());
+ } finally {
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
+ json.clear();
+ }
+ });
+ // Clear JSONArray after use, not sure if it does anything, but it might free
+ // some unused memory.
+ encoderArray.clear();
+ }
+
+ /**
+ * Gets specified {@link Encoder}.
+ *
+ * @return {@link Encoder}
+ * @param encoderName
+ */
+ default Encoder getEncoder(String encoderName) {
+ return encoders.get(encoderName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperPDP.java b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperPDP.java
new file mode 100644
index 0000000..19b93f2
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperPDP.java
@@ -0,0 +1,85 @@
+package org.usfirst.lib6647.subsystem.supercomponents;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.usfirst.lib6647.subsystem.PIDSuperSubsystem;
+import org.usfirst.lib6647.subsystem.SuperSubsystem;
+import org.usfirst.lib6647.util.ComponentInitException;
+
+import edu.wpi.first.wpilibj.PowerDistributionPanel;
+
+/**
+ * Interface to allow {@link PowerDistributionPanel} initialization via JSON.
+ * Subsystems declared need to extend {@link SuperSubsystem} or
+ * {@link PIDSuperSubsystem} and implement this interface in order to initialize
+ * {@link PowerDistributionPanel PDPs} declared in
+ * {@link SuperSubsystem#robotMap robotMap}.
+ */
+public interface SuperPDP {
+ /**
+ * HashMap storing the {@link SuperSubsystem}'s {@link PowerDistributionPanel
+ * PDPs}.
+ */
+ public HashMap PDPs = new HashMap();
+
+ /**
+ * Method to initialize {@link PowerDistributionPanel PDPs} declared in the
+ * {@link SuperSubsystem#robotMap robotMap} JSON file, and add them to the
+ * {@link #PDPs} HashMap using its declared name as its key.
+ *
+ * @param {@link SuperSubsystem#robotMap}
+ * @param {@link SuperSubsystem#getName}
+ */
+ default void initPDPs(JSONObject robotMap, String subsystemName) {
+ // Create a JSONArray out of the declared objects.
+ JSONArray PDPArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems")).get(subsystemName))
+ .get("PDPs");
+ // Create a stream to cast each entry in the JSONArray into a JSONObject, in
+ // order to configure it using the values declared in the robotMap file.
+ Arrays.stream(PDPArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
+ try {
+ if (json.containsKey("name") && json.containsKey("module")) {
+
+ PowerDistributionPanel pdp;
+ try {
+ // Try to initialize an object from an index in the JSONArray.
+ pdp = new PowerDistributionPanel(Integer.parseInt(json.get("module").toString()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(
+ String.format("[!] INVALID OR EMPTY PORT VALUE FOR PDP '%1$s' IN SUBSYSTEM '%2$s'",
+ json.get("name").toString(), subsystemName));
+ }
+
+ // Put object in HashMap with its declared name as key after initialization and
+ // configuration.
+ PDPs.put(json.get("name").toString(), pdp);
+ } else {
+ System.out.println(String.format("[!] UNDECLARED OR EMPTY PDP ENTRY IN SUBSYSTEM '%s'",
+ subsystemName.toUpperCase()));
+ }
+ } catch (ComponentInitException e) {
+ System.out.println(e.getMessage());
+ } finally {
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
+ json.clear();
+ }
+ });
+ // Clear JSONArray after use, not sure if it does anything, but it might free
+ // some unused memory.
+ PDPArray.clear();
+ }
+
+ /**
+ * Gets specified {@link PowerDistributionPanel}.
+ *
+ * @return {@link PowerDistributionPanel}
+ * @param pdpName
+ */
+ default PowerDistributionPanel getPDP(String pdpName) {
+ return PDPs.get(pdpName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperSolenoid.java b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperSolenoid.java
new file mode 100644
index 0000000..9381a49
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperSolenoid.java
@@ -0,0 +1,103 @@
+package org.usfirst.lib6647.subsystem.supercomponents;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.usfirst.lib6647.subsystem.PIDSuperSubsystem;
+import org.usfirst.lib6647.subsystem.SuperSubsystem;
+import org.usfirst.lib6647.subsystem.hypercomponents.HyperSolenoid;
+import org.usfirst.lib6647.util.ComponentInitException;
+
+/**
+ * Interface to allow {@link HyperSolenoid} initialization via JSON. Subsystems
+ * declared need to extend {@link SuperSubsystem} or {@link PIDSuperSubsystem}
+ * and implement this interface in order to initialize {@link HyperSolenoid
+ * HyperSolenoids} declared in {@link SuperSubsystem#robotMap robotMap}.
+ */
+public interface SuperSolenoid {
+ /**
+ * HashMap storing the {@link SuperSubsystem}'s {@link HyperSolenoid
+ * HyperSolenoids}.
+ */
+ public HashMap solenoids = new HashMap();
+
+ /**
+ * Method to initialize {@link HyperSolenoid HyperSolenoids} declared in the
+ * {@link SuperSubsystem#robotMap robotMap} JSON file, and add them to the
+ * {@link #solenoids} HashMap using its declared name as its key.
+ *
+ * @param {@link SuperSubsystem#robotMap}
+ * @param {@link SuperSubsystem#getName}
+ */
+ default void initSolenoids(JSONObject robotMap, String subsystemName) {
+ // Create a JSONArray out of the declared objects.
+ JSONArray solenoidArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
+ .get(subsystemName)).get("solenoids");
+ // Create a stream to cast each entry in the JSONArray into a JSONObject, in
+ // order to configure it using the values declared in the robotMap file.
+ Arrays.stream(solenoidArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
+ try {
+ if (json.containsKey("name") && json.containsKey("channel")) {
+
+ HyperSolenoid solenoid;
+ try {
+ // Create an object out of one index in the JSONArray.
+ solenoid = new HyperSolenoid(Integer.parseInt(json.get("channel").toString()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format(
+ "[!] INVALID OR EMPTY CHANNEL VALUE(S) FOR SOLENOID '%1$s' IN SUBSYSTEM '%2$s'",
+ json.get("name").toString(), subsystemName));
+ }
+
+ if (json.containsKey("initialValue"))
+ setInitialValue(json, solenoid);
+
+ // Put object in HashMap with its declared name as key after initialization and
+ // configuration.
+ solenoids.put(json.get("name").toString(), solenoid);
+ } else {
+ System.out.println(String.format("[!] UNDECLARED OR EMPTY SOLENOID ENTRY IN SUBSYSTEM '%s'",
+ subsystemName.toUpperCase()));
+ }
+ } catch (ComponentInitException e) {
+ System.out.println(e.getMessage());
+ } finally {
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
+ json.clear();
+ }
+ });
+ // Clear JSONArray after use, not sure if it does anything, but it might free
+ // some unused memory.
+ solenoidArray.clear();
+ }
+
+ /**
+ * Sets a given {@link HyperSolenoid}'s inverted value from a
+ * {@link JSONObject}.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperSolenoid}
+ * @throws ComponentInitException if {@link JSONObject} key is defined, but
+ * empty.
+ */
+ default void setInitialValue(JSONObject json, HyperSolenoid solenoid) throws ComponentInitException {
+ if (json.get("initialValue").toString().isEmpty())
+ throw new ComponentInitException(String.format("[!] EMPTY INITIAL VALUE FOR SOLENOID '%s'.",
+ json.get("name").toString().toUpperCase()));
+
+ solenoid.set(Boolean.parseBoolean(json.get("initialValue").toString()));
+ }
+
+ /**
+ * Gets specified {@link HyperSolenoid}.
+ *
+ * @return {@link HyperSolenoid}
+ * @param solenoidName
+ */
+ default HyperSolenoid getSolenoid(String solenoidName) {
+ return solenoids.get(solenoidName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperTalon.java b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperTalon.java
new file mode 100644
index 0000000..88a6c42
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperTalon.java
@@ -0,0 +1,284 @@
+package org.usfirst.lib6647.subsystem.supercomponents;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import com.ctre.phoenix.motorcontrol.NeutralMode;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.usfirst.lib6647.subsystem.PIDSuperSubsystem;
+import org.usfirst.lib6647.subsystem.SuperSubsystem;
+import org.usfirst.lib6647.subsystem.hypercomponents.HyperTalon;
+import org.usfirst.lib6647.util.ComponentInitException;
+import org.usfirst.lib6647.util.MotorUtils;
+
+/**
+ * Interface to allow {@link HyperTalon} initialization via JSON. Subsystems
+ * declared need to extend {@link SuperSubsystem} or {@link PIDSuperSubsystem}
+ * and implement this interface in order to initialize {@link HyperTalon
+ * HyperTalons} declared in {@link SuperSubsystem#robotMap robotMap}.
+ */
+public interface SuperTalon extends MotorUtils {
+ /**
+ * HashMap storing the {@link SuperSubsystem}'s {@link HyperTalon HyperTalons}.
+ */
+ public HashMap talons = new HashMap();
+
+ /**
+ * Method to initialize {@link HyperTalon HyperTalons} declared in the
+ * {@link SuperSubsystem#robotMap robotMap} JSON file, and add them to the
+ * {@link #talons} HashMap using its declared name as its key.
+ *
+ * @param {@link SuperSubsystem#robotMap}
+ * @param {@link SuperSubsystem#getName}
+ */
+ default void initTalons(JSONObject robotMap, String subsystemName) {
+ // Create a JSONArray out of the declared objects.
+ JSONArray talonArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems")).get(subsystemName))
+ .get("talons");
+ // Create a stream to cast each entry in the JSONArray into a JSONObject, in
+ // order to configure it using the values declared in the robotMap file.
+ Arrays.stream(talonArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
+ try {
+ if (json.containsKey("name") && json.containsKey("port")) {
+
+ HyperTalon talon;
+ try {
+ // Try to initialize an object from an index in the JSONArray.
+ talon = new HyperTalon(Integer.parseInt(json.get("port").toString()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(
+ String.format("[!] INVALID OR EMPTY PORT VALUE FOR TALON '%1$s' IN SUBSYSTEM '%2$s'",
+ json.get("name").toString(), subsystemName));
+ }
+ talon.setName(json.get("name").toString());
+
+ if (json.containsKey("limiter"))
+ setLimiter(json, talon);
+
+ if (json.containsKey("neutralMode"))
+ setNeutralMode(json, talon);
+
+ if (json.containsKey("inverted"))
+ setInverted(json, talon);
+
+ if (json.containsKey("loopRamp")) {
+ setClosedloopRamp(json, talon);
+ setOpenloopRamp(json, talon);
+ }
+
+ if (json.containsKey("sensor"))
+ setSensors(json, talon);
+
+ if (json.containsKey("pid"))
+ setPIDValues(json, talon);
+
+ talon.stopMotor();
+
+ // Put object in HashMap with its declared name as key after initialization and
+ // configuration.
+ talons.put(json.get("name").toString(), talon);
+ } else {
+ System.out.println(String.format("[!] UNDECLARED OR EMPTY TALON ENTRY IN SUBSYSTEM '%s'",
+ subsystemName.toUpperCase()));
+ }
+ } catch (ComponentInitException e) {
+ System.out.println(e.getMessage());
+ } finally {
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
+ json.clear();
+ }
+ });
+ // Clear JSONArray after use, not sure if it does anything, but it might free
+ // some unused memory.
+ talonArray.clear();
+ }
+
+ /**
+ * Sets a given {@link HyperTalon}'s {@link HyperTalon#limiter limiter} value
+ * from a {@link JSONObject}. Max value is 1, min value is 0 (which would make
+ * the {@link HyperTalon} stop).
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperTalon}
+ * @throws ComponentInitException if {@link JSONObject} key is defined, but
+ * empty or not a number.
+ */
+ default void setLimiter(JSONObject json, HyperTalon talon) throws ComponentInitException {
+ try {
+ double limiter = Double.parseDouble(json.get("limiter").toString());
+ talon.setLimiter(limiter < 0.0 ? 0.0 : limiter > 1.0 ? 1.0 : limiter);
+ } catch (NullPointerException e) {
+ throw new ComponentInitException(String.format("[!] EMPTY LIMITER VALUE FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format("[!] INVALID LIMITER VALUE FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+ }
+ }
+
+ /**
+ * Sets a given {@link HyperTalon}'s inverted value from a {@link JSONObject}.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperTalon}
+ * @throws ComponentInitException if {@link JSONObject} key is defined, but
+ * empty.
+ */
+ default void setInverted(JSONObject json, HyperTalon talon) throws ComponentInitException {
+ if (json.get("inverted").toString().isEmpty())
+ throw new ComponentInitException(String.format("[!] EMPTY INVERTED VALUE FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+
+ talon.setInverted(Boolean.parseBoolean(json.get("inverted").toString()));
+ }
+
+ /**
+ * Sets a given {@link HyperTalon}'s {@link NeutralMode} from a
+ * {@link JSONObject} key.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperTalon}
+ * @throws ComponentInitException if {@link JSONObject} key is defined, but
+ * empty or invalid.
+ *
+ * @note There are three types of {@link NeutralMode NeutralModes}:
+ * {@link NeutralMode#Coast Coast}, {@link NeutralMode#Brake Brake}, and
+ * {@link NeutralMode#EEPROMSetting EEPROMSetting}. All of which must
+ * share the same name in the {@link JSONObject}.
+ */
+ default void setNeutralMode(JSONObject json, HyperTalon talon) throws ComponentInitException {
+ if (getNeutralMode(json.get("neutralMode").toString()) == null)
+ throw new ComponentInitException(
+ String.format("[!] INVALID OR EMPTY NEUTRAL MODE CONFIGURATION FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+
+ talon.setNeutralMode(getNeutralMode(json.get("neutralMode").toString()));
+ }
+
+ /**
+ * Sets a given {@link HyperTalon}'s ClosedloopRamp from a {@link JSONObject}
+ * key.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperTalon}
+ * @throws ComponentInitException if {@link JSONObject} key is not found, or its
+ * subkeys are invalid or empty.
+ */
+ default void setClosedloopRamp(JSONObject json, HyperTalon talon) throws ComponentInitException {
+ try {
+ JSONObject closed = (JSONObject) ((JSONObject) json.get("loopRamp")).get("closed");
+
+ if (closed.containsKey("timeoutMs"))
+ talon.configClosedloopRamp(Double.parseDouble(closed.get("secondsFromNeutralToFull").toString()),
+ Integer.parseInt(closed.get("timeoutMs").toString()));
+ else
+ talon.configClosedloopRamp(Double.parseDouble(closed.get("secondsFromNeutralToFull").toString()));
+ } catch (NullPointerException e) {
+ throw new ComponentInitException(String.format("[!] EMPTY CLOSEDLOOP RAMP VALUE(S) FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format("[!] INVALID CLOSEDLOOP RAMP VALUE(S) FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+ }
+ }
+
+ /**
+ * Sets a given {@link HyperTalon}'s OpenloopRamp from a {@link JSONObject} key.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperTalon}
+ * @throws ComponentInitException if {@link JSONObject} key is not found, or its
+ * subkeys are invalid or empty.
+ */
+ default void setOpenloopRamp(JSONObject json, HyperTalon talon) throws ComponentInitException {
+ try {
+ JSONObject open = (JSONObject) ((JSONObject) json.get("loopRamp")).get("open");
+
+ if (open.containsKey("timeoutMs"))
+ talon.configOpenloopRamp(Double.parseDouble(open.get("secondsFromNeutralToFull").toString()),
+ Integer.parseInt(open.get("timeoutMs").toString()));
+ else
+ talon.configOpenloopRamp(Double.parseDouble(open.get("secondsFromNeutralToFull").toString()));
+ } catch (NullPointerException e) {
+ throw new ComponentInitException(String.format("[!] EMPTY OPENLOOP RAMP VALUE(S) FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format("[!] INVALID OPENLOOP RAMP VALUE(S) FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+ }
+ }
+
+ /**
+ * Sets a given {@link HyperTalon}'s sensors from a {@link JSONObject} key
+ * (fairly limited in terms of configuration at the moment).
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperTalon}
+ * @throws ComponentInitException if {@link JSONObject} key is not found, or its
+ * subkeys are invalid or empty.
+ */
+ default void setSensors(JSONObject json, HyperTalon talon) throws ComponentInitException {
+ try {
+ JSONObject sensor = (JSONObject) json.get("sensor");
+ JSONObject feedback = (JSONObject) sensor.get("feedback");
+
+ talon.configSelectedFeedbackSensor(getFeedbackDevice(feedback.get("feedbackDevice").toString()),
+ Integer.parseInt(feedback.get("pidIdx").toString()),
+ Integer.parseInt(feedback.get("timeoutMs").toString()));
+
+ talon.setSensorPhase(Boolean.parseBoolean(sensor.get("phase").toString()));
+
+ talon.setSelectedSensorPosition(Integer.parseInt(sensor.get("sensorPos").toString()),
+ Integer.parseInt(sensor.get("pidIdx").toString()),
+ Integer.parseInt(sensor.get("timeoutMs").toString()));
+ } catch (NullPointerException e) {
+ throw new ComponentInitException(String.format("[!] EMPTY SENSOR VALUE(S) FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format("[!] INVALID SENSOR VALUE(S) FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+ }
+ }
+
+ /**
+ * Sets a given {@link HyperTalon}'s PID values from a {@link JSONObject} key.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperTalon}
+ * @throws ComponentInitException if {@link JSONObject} key is not found, or its
+ * subkeys are invalid or empty.
+ */
+ default void setPIDValues(JSONObject json, HyperTalon talon) throws ComponentInitException {
+ try {
+ JSONObject pid = (JSONObject) json.get("pid");
+
+ talon.config_kP(Integer.parseInt(pid.get("slotIdx").toString()),
+ Double.parseDouble(pid.get("p").toString()));
+ talon.config_kI(Integer.parseInt(pid.get("slotIdx").toString()),
+ Double.parseDouble(pid.get("i").toString()));
+ talon.config_kD(Integer.parseInt(pid.get("slotIdx").toString()),
+ Double.parseDouble(pid.get("d").toString()));
+ talon.config_kF(Integer.parseInt(pid.get("slotIdx").toString()),
+ Double.parseDouble(pid.get("f").toString()));
+ } catch (NullPointerException e) {
+ throw new ComponentInitException(
+ String.format("[!] EMPTY PID VALUE(S) FOR TALON '%s'.", json.get("name").toString().toUpperCase()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format("[!] INVALID PID VALUE(S) FOR TALON '%s'.",
+ json.get("name").toString().toUpperCase()));
+ }
+ }
+
+ /**
+ * Gets specified {@link HyperTalon}.
+ *
+ * @return {@link HyperTalon}
+ * @param talonName
+ */
+ default HyperTalon getTalon(String talonName) {
+ return talons.get(talonName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperUltrasonic.java b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperUltrasonic.java
new file mode 100644
index 0000000..f68c9bf
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperUltrasonic.java
@@ -0,0 +1,84 @@
+package org.usfirst.lib6647.subsystem.supercomponents;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.usfirst.lib6647.subsystem.PIDSuperSubsystem;
+import org.usfirst.lib6647.subsystem.SuperSubsystem;
+import org.usfirst.lib6647.util.ComponentInitException;
+
+import edu.wpi.first.wpilibj.Ultrasonic;
+
+/**
+ * Interface to allow {@link Ultrasonic} initialization via JSON. Subsystems
+ * declared need to extend {@link SuperSubsystem} or {@link PIDSuperSubsystem}
+ * and implement this interface in order to initialize {@link Ultrasonic
+ * Ultrasonics} declared in {@link SuperSubsystem#robotMap robotMap}.
+ */
+public interface SuperUltrasonic {
+ /**
+ * HashMap storing the {@link SuperSubsystem}'s {@link Ultrasonic Ultrasonics}.
+ */
+ public HashMap ultrasonics = new HashMap();
+
+ /**
+ * Method to initialize {@link Ultrasonic Ultrasonics} declared in the
+ * {@link SuperSubsystem#robotMap robotMap} JSON file, and add them to the
+ * {@link #ultrasonics} HashMap using its declared name as its key.
+ *
+ * @param {@link SuperSubsystem#robotMap}
+ * @param {@link SuperSubsystem#getName}
+ */
+ default void initUltrasonics(JSONObject robotMap, String subsystemName) {
+ // Create a JSONArray out of the declared objects.
+ JSONArray ultrasonicArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems"))
+ .get(subsystemName)).get("ultrasonics");
+ // Create a stream to cast each entry in the JSONArray into a JSONObject, in
+ // order to configure it using the values declared in the robotMap file.
+ Arrays.stream(ultrasonicArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
+ try {
+ if (json.containsKey("name") && json.containsKey("pingChannel") && json.containsKey("echoChannel")) {
+
+ Ultrasonic ultrasonic;
+ try {
+ // Create an object out of one index in the JSONArray.
+ ultrasonic = new Ultrasonic(Integer.parseInt(json.get("pingChannel").toString()),
+ Integer.parseInt(json.get("echoChannel").toString()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(
+ String.format("[!] INVALID OR EMPTY VALUE(S) FOR ULTRASONIC '%1$s' IN SUBSYSTEM '%2$s'",
+ json.get("name").toString(), subsystemName));
+ }
+
+ // Put object in HashMap with its declared name as key after initialization and
+ // configuration.
+ ultrasonics.put(json.get("name").toString(), ultrasonic);
+ } else {
+ System.out.println(String.format("[!] UNDECLARED OR EMPTY ULTRASONIC ENTRY IN SUBSYSTEM '%s'",
+ subsystemName.toUpperCase()));
+ }
+ } catch (ComponentInitException e) {
+ System.out.println(e.getMessage());
+ } finally {
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
+ json.clear();
+ }
+ });
+ // Clear JSONArray after use, not sure if it does anything, but it might free
+ // some unused memory.
+ ultrasonicArray.clear();
+ }
+
+ /**
+ * Gets specified {@link Ultrasonic}.
+ *
+ * @return {@link Ultrasonic}
+ * @param ultrasonicName
+ */
+ default Ultrasonic getUltrasonic(String ultrasonicName) {
+ return ultrasonics.get(ultrasonicName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperVictor.java b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperVictor.java
new file mode 100644
index 0000000..98dff37
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/subsystem/supercomponents/SuperVictor.java
@@ -0,0 +1,219 @@
+package org.usfirst.lib6647.subsystem.supercomponents;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import com.ctre.phoenix.motorcontrol.NeutralMode;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.usfirst.lib6647.subsystem.PIDSuperSubsystem;
+import org.usfirst.lib6647.subsystem.SuperSubsystem;
+import org.usfirst.lib6647.subsystem.hypercomponents.HyperVictor;
+import org.usfirst.lib6647.util.ComponentInitException;
+import org.usfirst.lib6647.util.MotorUtils;
+
+/**
+ * Interface to allow {@link HyperVictor} initialization via JSON. Subsystems
+ * declared need to extend {@link SuperSubsystem} or {@link PIDSuperSubsystem}
+ * and implement this interface in order to initialize {@link HyperTalon
+ * HyperVictors} declared in {@link SuperSubsystem#robotMap robotMap}.
+ */
+public interface SuperVictor extends MotorUtils {
+ /**
+ * HashMap storing the {@link SuperSubsystem}'s {@link HyperVictor
+ * HyperVictors}.
+ */
+ public HashMap victors = new HashMap();
+
+ /**
+ * Method to initialize {@link HyperVictor HyperVictors} declared in the
+ * {@link SuperSubsystem#robotMap robotMap} JSON file, and add them to the
+ * {@link #victors} HashMap using its declared name as its key.
+ *
+ * @param {@link SuperSubsystem#robotMap}
+ * @param {@link SuperSubsystem#getName}
+ */
+ default void initVictors(JSONObject robotMap, String subsystemName) {
+ // Create a JSONArray out of the declared objects.
+ JSONArray victorArray = (JSONArray) ((JSONObject) ((JSONObject) robotMap.get("subsystems")).get(subsystemName))
+ .get("victors");
+ // Create a stream to cast each entry in the JSONArray into a JSONObject, in
+ // order to configure it using the values declared in the robotMap file.
+ Arrays.stream(victorArray.toArray()).map(json -> (JSONObject) json).forEach(json -> {
+ try {
+ if (json.containsKey("name") && json.containsKey("port")) {
+
+ HyperVictor victor;
+ try {
+ // Create an object out of one index in the JSONArray.
+ victor = new HyperVictor(Integer.parseInt(json.get("port").toString()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(
+ String.format("[!] INVALID OR EMPTY PORT VALUE FOR VICTOR '%1$s' IN SUBSYSTEM '%2$s'",
+ json.get("name").toString(), subsystemName));
+ }
+ victor.setName(json.get("name").toString());
+
+ if (json.containsKey("limiter"))
+ setLimiter(json, victor);
+
+ if (json.containsKey("neutralMode"))
+ setNeutralMode(json, victor);
+
+ if (json.containsKey("inverted"))
+ setInverted(json, victor);
+
+ if (json.containsKey("loopRamp")) {
+ setClosedloopRamp(json, victor);
+ setOpenloopRamp(json, victor);
+ }
+
+ victor.stopMotor();
+
+ // Put object in HashMap with its declared name as key after initialization and
+ // configuration.
+ victors.put(json.get("name").toString(), victor);
+ } else {
+ System.out.println(String.format("[!] UNDECLARED OR EMPTY VICTOR ENTRY IN SUBSYSTEM '%s'",
+ subsystemName.toUpperCase()));
+ }
+ } catch (ComponentInitException e) {
+ System.out.println(e.getMessage());
+ } finally {
+ // Clear JSONObject after use, not sure if it does anything, but it might free
+ // some unused memory.
+ json.clear();
+ }
+ });
+ // Clear JSONArray after use, not sure if it does anything, but it might free
+ // some unused memory.
+ victorArray.clear();
+ }
+
+ /**
+ * Sets a given {@link HyperVictor}'s {@link HyperVictor#limiter limiter} value
+ * from a {@link JSONObject}. Max value is 1, min value is 0 (which would make
+ * the {@link HyperVictor} stop).
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperVictor}
+ * @throws ComponentInitException if {@link JSONObject} key is defined, but
+ * empty or not a number.
+ */
+ default void setLimiter(JSONObject json, HyperVictor victor) throws ComponentInitException {
+ try {
+ double limiter = Double.parseDouble(json.get("limiter").toString());
+ victor.setLimiter(limiter < 0.0 ? 0.0 : limiter > 1.0 ? 1.0 : limiter);
+ } catch (NullPointerException e) {
+ throw new ComponentInitException(String.format("[!] EMPTY LIMITER VALUE FOR VICTOR '%s'.",
+ json.get("name").toString().toUpperCase()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format("[!] INVALID LIMITER VALUE FOR VICTOR '%s'.",
+ json.get("name").toString().toUpperCase()));
+ }
+ }
+
+ /**
+ * Sets a given {@link HyperVictor}'s inverted value from a {@link JSONObject}.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperVictor}
+ * @throws ComponentInitException if {@link JSONObject} key is defined, but
+ * empty.
+ */
+ default void setInverted(JSONObject json, HyperVictor victor) throws ComponentInitException {
+ if (json.get("inverted").toString().isEmpty())
+ throw new ComponentInitException(String.format("[!] EMPTY INVERTED VALUE FOR VICTOR '%s'.",
+ json.get("name").toString().toUpperCase()));
+
+ victor.setInverted(Boolean.parseBoolean(json.get("inverted").toString()));
+ }
+
+ /**
+ * Sets a given {@link HyperVictor}'s {@link NeutralMode} from a
+ * {@link JSONObject} key.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperVictor}
+ * @throws ComponentInitException if {@link JSONObject} key is defined, but
+ * empty or invalid.
+ *
+ * @note There are three types of {@link NeutralMode NeutralModes}:
+ * {@link NeutralMode#Coast Coast}, {@link NeutralMode#Brake Brake}, and
+ * {@link NeutralMode#EEPROMSetting EEPROMSetting}. All of which must
+ * share the same name in the {@link JSONObject}.
+ */
+ default void setNeutralMode(JSONObject json, HyperVictor victor) throws ComponentInitException {
+ if (getNeutralMode(json.get("neutralMode").toString()) == null)
+ throw new ComponentInitException(
+ String.format("[!] INVALID OR EMPTY NEUTRAL MODE CONFIGURATION FOR VICTOR '%s'.",
+ json.get("name").toString().toUpperCase()));
+
+ victor.setNeutralMode(getNeutralMode(json.get("neutralMode").toString()));
+ }
+
+ /**
+ * Sets a given {@link HyperVictor}'s ClosedloopRamp from a {@link JSONObject}
+ * key.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperVictor}
+ * @throws ComponentInitException if {@link JSONObject} key is not found, or its
+ * subkeys are invalid or empty.
+ */
+ default void setClosedloopRamp(JSONObject json, HyperVictor victor) throws ComponentInitException {
+ try {
+ JSONObject closed = (JSONObject) ((JSONObject) json.get("loopRamp")).get("closed");
+
+ if (closed.containsKey("timeoutMs"))
+ victor.configClosedloopRamp(Double.parseDouble(closed.get("secondsFromNeutralToFull").toString()),
+ Integer.parseInt(closed.get("timeoutMs").toString()));
+ else
+ victor.configClosedloopRamp(Double.parseDouble(closed.get("secondsFromNeutralToFull").toString()));
+ } catch (NullPointerException e) {
+ throw new ComponentInitException(String.format("[!] EMPTY CLOSEDLOOP RAMP VALUE(S) FOR VICTOR '%s'.",
+ json.get("name").toString().toUpperCase()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format("[!] INVALID CLOSEDLOOP RAMP VALUE(S) FOR VICTOR '%s'.",
+ json.get("name").toString().toUpperCase()));
+ }
+ }
+
+ /**
+ * Sets a given {@link HyperVictor}'s OpenloopRamp from a {@link JSONObject}
+ * key.
+ *
+ * @param {@link JSONObject}
+ * @param {@link HyperVictor}
+ * @throws ComponentInitException if {@link JSONObject} key is not found, or its
+ * subkeys are invalid or empty.
+ */
+ default void setOpenloopRamp(JSONObject json, HyperVictor victor) throws ComponentInitException {
+ try {
+ JSONObject open = (JSONObject) ((JSONObject) json.get("loopRamp")).get("open");
+
+ if (open.containsKey("timeoutMs"))
+ victor.configOpenloopRamp(Double.parseDouble(open.get("secondsFromNeutralToFull").toString()),
+ Integer.parseInt(open.get("timeoutMs").toString()));
+ else
+ victor.configOpenloopRamp(Double.parseDouble(open.get("secondsFromNeutralToFull").toString()));
+ } catch (NullPointerException e) {
+ throw new ComponentInitException(String.format("[!] EMPTY OPENLOOP RAMP VALUE(S) FOR VICTOR '%s'.",
+ json.get("name").toString().toUpperCase()));
+ } catch (NumberFormatException e) {
+ throw new ComponentInitException(String.format("[!] INVALID OPENLOOP RAMP VALUE(S) FOR VICTOR '%s'.",
+ json.get("name").toString().toUpperCase()));
+ }
+ }
+
+ /**
+ * Gets specified {@link HyperVictor}.
+ *
+ * @return {@link HyperVictor}
+ * @param victorName
+ */
+ default HyperVictor getVictor(String victorName) {
+ return victors.get(victorName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/util/ComponentInitException.java b/src/main/java/org/usfirst/lib6647/util/ComponentInitException.java
new file mode 100644
index 0000000..5cff574
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/util/ComponentInitException.java
@@ -0,0 +1,21 @@
+package org.usfirst.lib6647.util;
+
+/**
+ * {@link Exception} for errors while initializing Super/HyperComponents.
+ */
+public class ComponentInitException extends Exception {
+
+ /**
+ * Serial Version UID.
+ */
+ private static final long serialVersionUID = 7668209987656891489L;
+
+ /**
+ * {@link Exception} for errors while initializing Super/HyperComponents.
+ *
+ * @param message
+ */
+ public ComponentInitException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/util/Direction.java b/src/main/java/org/usfirst/lib6647/util/Direction.java
deleted file mode 100644
index 94edb31..0000000
--- a/src/main/java/org/usfirst/lib6647/util/Direction.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.usfirst.lib6647.util;
-
-/**
- * Enum listing possible movement directions, for readability purposes.
- */
-public enum Direction {
- UP, DOWN, FRONT, BACK, LEFT, RIGHT, FORWARD, BACKWARD, IN, OUT, NONE
-}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/util/MotorUtils.java b/src/main/java/org/usfirst/lib6647/util/MotorUtils.java
index 9761b51..4d11d68 100644
--- a/src/main/java/org/usfirst/lib6647/util/MotorUtils.java
+++ b/src/main/java/org/usfirst/lib6647/util/MotorUtils.java
@@ -1,44 +1,28 @@
package org.usfirst.lib6647.util;
+import org.json.simple.JSONObject;
+
+import edu.wpi.first.wpilibj.CounterBase.EncodingType;
+
import com.ctre.phoenix.motorcontrol.FeedbackDevice;
import com.ctre.phoenix.motorcontrol.NeutralMode;
-import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX;
-import com.ctre.phoenix.motorcontrol.can.WPI_VictorSPX;
-
-import org.json.simple.JSONObject;
/**
- * Interface for converting String values to CTRE Objects.
+ * SuperInterface for converting String values from a {@link JSONObject} to enum
+ * types.
*/
public interface MotorUtils {
/**
- * Sets a given Talon's inverted status from the JSON configuration.
- *
- * @param json
- * @param talon
- * @throws Exception
- */
- default void setInverted(JSONObject json, WPI_TalonSRX talon) throws Exception {
- talon.setInverted(Boolean.parseBoolean(json.get("inverted").toString()));
- }
-
- /**
- * Sets a given Victor's inverted status from the JSON configuration.
- *
- * @param json
- * @param victor
- * @throws Exception
- */
- default void setInverted(JSONObject json, WPI_VictorSPX victor) throws Exception {
- victor.setInverted(Boolean.parseBoolean(json.get("inverted").toString()));
- }
-
- /**
- * Method to convert a String to its respective NeutralMode.
+ * Method to convert a String value to its respective {@link NeutralMode}.
*
* @param neutralMode
- * @return NeutralMode
+ * @return {@link NeutralMode}
+ *
+ * @note There are three types of {@link NeutralMode NeutralModes}:
+ * {@link NeutralMode#Coast}, {@link NeutralMode#Brake}, and
+ * {@link NeutralMode#EEPROMSetting}. All of which should share the same
+ * name in the {@link JSONObject}.
*/
default NeutralMode getNeutralMode(String neutralMode) {
switch (neutralMode) {
@@ -54,76 +38,22 @@ default NeutralMode getNeutralMode(String neutralMode) {
}
/**
- * Sets a given Talon's inverted status from the JSON configuration.
- *
- * @param json
- * @param talon
- * @throws Exception
- */
- default void setNeutralMode(JSONObject json, WPI_TalonSRX talon) throws Exception {
- talon.setNeutralMode(getNeutralMode(json.get("neutralMode").toString()));
- }
-
- /**
- * Sets a given Victor's inverted status from the JSON configuration.
- *
- * @param json
- * @param victor
- * @throws Exception
- */
- default void setNeutralMode(JSONObject json, WPI_VictorSPX victor) throws Exception {
- victor.setNeutralMode(getNeutralMode(json.get("neutralMode").toString()));
- }
-
- /**
- * Sets a given Talon's loopramp from the JSON configuration.
- *
- * @param json
- * @param talon
- * @throws Exception
- */
- default void setLoopRamp(JSONObject json, WPI_TalonSRX talon) throws Exception {
- JSONObject closed = (JSONObject) ((JSONObject) json.get("loopRamp")).get("closed"),
- open = (JSONObject) ((JSONObject) json.get("loopRamp")).get("open");
-
- if (closed.containsKey("timeoutMs") && open.containsKey("timeoutMs")) {
- talon.configClosedloopRamp(Double.parseDouble(closed.get("secondsFromNeutralToFull").toString()),
- Integer.parseInt(closed.get("timeoutMs").toString()));
- talon.configOpenloopRamp(Double.parseDouble(open.get("secondsFromNeutralToFull").toString()),
- Integer.parseInt(open.get("timeoutMs").toString()));
- } else {
- talon.configClosedloopRamp(Double.parseDouble(closed.get("secondsFromNeutralToFull").toString()));
- talon.configOpenloopRamp(Double.parseDouble(open.get("secondsFromNeutralToFull").toString()));
- }
- }
-
- /**
- * Sets a given Victor's loopramp from the JSON configuration.
- *
- * @param json
- * @param victor
- * @throws Exception
- */
- default void setLoopRamp(JSONObject json, WPI_VictorSPX victor) throws Exception {
- JSONObject closed = (JSONObject) ((JSONObject) json.get("loopRamp")).get("closed"),
- open = (JSONObject) ((JSONObject) json.get("loopRamp")).get("open");
-
- if (closed.containsKey("timeoutMs") && open.containsKey("timeoutMs")) {
- victor.configClosedloopRamp(Double.parseDouble(closed.get("secondsFromNeutralToFull").toString()),
- Integer.parseInt(closed.get("timeoutMs").toString()));
- victor.configOpenloopRamp(Double.parseDouble(open.get("secondsFromNeutralToFull").toString()),
- Integer.parseInt(open.get("timeoutMs").toString()));
- } else {
- victor.configClosedloopRamp(Double.parseDouble(closed.get("secondsFromNeutralToFull").toString()));
- victor.configOpenloopRamp(Double.parseDouble(open.get("secondsFromNeutralToFull").toString()));
- }
- }
-
- /**
- * Method to convert a String to its respective FeedbackDevice.
+ * Method to convert a String to its respective {@link FeedbackDevice}.
*
* @param feedbackDevice
- * @return FeedbackDevice
+ * @return {@link FeedbackDevice}
+ *
+ * @note There are eleven types of {@link FeedbackDevice FeedbackDevices}:
+ * {@link FeedbackDevice#QuadEncoder}, {@link FeedbackDevice#Analog},
+ * {@link FeedbackDevice#Tachometer},
+ * {@link FeedbackDevice#PulseWidthEncodedPosition},
+ * {@link FeedbackDevice#SensorSum},
+ * {@link FeedbackDevice#SensorDifference},
+ * {@link FeedbackDevice#RemoteSensor0},
+ * {@link FeedbackDevice#RemoteSensor1},
+ * {@link FeedbackDevice#SoftwareEmulatedSensor},
+ * {@link FeedbackDevice#CTRE_MagEncoder_Absolute},
+ * {@link FeedbackDevice#CTRE_MagEncoder_Relative}
*/
default FeedbackDevice getFeedbackDevice(String feedbackDevice) {
switch (feedbackDevice) {
@@ -155,41 +85,22 @@ default FeedbackDevice getFeedbackDevice(String feedbackDevice) {
}
/**
- * Sets a given Talon's sensors from the JSON configuration (fairly limited in
- * terms of customizability at the moment).
+ * Method to convert a String to its respective {@link EncodingType}.
*
- * @param json
- * @param talon
- * @throws Exception
+ * @param encodingType
+ * @return {@link EncodingType}
*/
- default void setSensors(JSONObject json, WPI_TalonSRX talon) throws Exception {
- JSONObject sensor = (JSONObject) json.get("sensor");
- JSONObject feedback = (JSONObject) sensor.get("feedback");
-
- talon.configSelectedFeedbackSensor(getFeedbackDevice(feedback.get("feedbackDevice").toString()),
- Integer.parseInt(feedback.get("pidIdx").toString()),
- Integer.parseInt(feedback.get("timeoutMs").toString()));
-
- talon.setSensorPhase(Boolean.parseBoolean(sensor.get("phase").toString()));
-
- talon.setSelectedSensorPosition(Integer.parseInt(sensor.get("sensorPos").toString()),
- Integer.parseInt(sensor.get("pidIdx").toString()),
- Integer.parseInt(sensor.get("timeoutMs").toString()));
+ default EncodingType getEncodingType(String encodingType) {
+ switch (encodingType) {
+ case "k1X":
+ return EncodingType.k1X;
+ case "k2X":
+ return EncodingType.k2X;
+ case "k4X":
+ return EncodingType.k4X;
+ default:
+ return null;
+ }
}
- /**
- * Sets a given Talon's PID values from the JSON configuration.
- *
- * @param json
- * @param talon
- * @throws Exception
- */
- default void setPIDValues(JSONObject json, WPI_TalonSRX talon) throws Exception {
- JSONObject pid = (JSONObject) json.get("pid");
-
- talon.config_kP(Integer.parseInt(pid.get("slotIdx").toString()), Double.parseDouble(pid.get("p").toString()));
- talon.config_kI(Integer.parseInt(pid.get("slotIdx").toString()), Double.parseDouble(pid.get("i").toString()));
- talon.config_kD(Integer.parseInt(pid.get("slotIdx").toString()), Double.parseDouble(pid.get("d").toString()));
- talon.config_kF(Integer.parseInt(pid.get("slotIdx").toString()), Double.parseDouble(pid.get("f").toString()));
- }
}
\ No newline at end of file
diff --git a/src/main/java/org/usfirst/lib6647/util/MoveDirection.java b/src/main/java/org/usfirst/lib6647/util/MoveDirection.java
new file mode 100644
index 0000000..974f63f
--- /dev/null
+++ b/src/main/java/org/usfirst/lib6647/util/MoveDirection.java
@@ -0,0 +1,11 @@
+package org.usfirst.lib6647.util;
+
+import edu.wpi.first.wpilibj.command.Command;
+
+/**
+ * Enum listing possible movement directions, useful for commands. Mostly useful
+ * for {@link Command Commands}.
+ */
+public enum MoveDirection {
+ UP, DOWN, FRONT, BACK, LEFT, RIGHT, FORWARD, BACKWARD, IN, OUT, NONE
+}
\ No newline at end of file