diff --git a/patches/src/main/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java b/patches/src/main/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java index e9fe3c6..20b7f73 100644 --- a/patches/src/main/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java +++ b/patches/src/main/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java @@ -3,6 +3,8 @@ import java.nio.IntBuffer; import java.nio.LongBuffer; +import jaci.openrio.toast.core.loader.simulation.SimulationData; + /** * Analog Input/Output */ @@ -92,7 +94,7 @@ public static boolean getAnalogTriggerTriggerState(long analog_trigger_pointer){ } public static short getAnalogValue(long analog_port_pointer){ - return 0; + return SimulationData.analogValues[(int) analog_port_pointer]; } public static double getAnalogVoltage(long analog_port_pointer){ diff --git a/patches/src/main/java/edu/wpi/first/wpilibj/hal/EncoderJNI.java b/patches/src/main/java/edu/wpi/first/wpilibj/hal/EncoderJNI.java new file mode 100644 index 0000000..b5476ca --- /dev/null +++ b/patches/src/main/java/edu/wpi/first/wpilibj/hal/EncoderJNI.java @@ -0,0 +1,61 @@ +package edu.wpi.first.wpilibj.hal; + +import java.nio.IntBuffer; + +import jaci.openrio.toast.core.loader.simulation.encoder.EncoderReg; + +/** + * JNIWrapper for encoders + */ +public class EncoderJNI extends JNIWrapper { + + public static long initializeEncoder(byte port_a_module, int port_a_pin, + boolean port_a_analog_trigger, byte port_b_module, int port_b_pin, boolean port_b_analog_trigger, + boolean reverseDirection, IntBuffer index){ + long pointer = EncoderReg.wrappers.size(); + EncoderReg.wrappers.put(pointer, new EncoderReg.EncoderWrapper()); + return pointer; + } + + public static void freeEncoder(long encoder_pointer){ + } + + public static void resetEncoder(long encoder_pointer){ + } + + public static int getEncoder(long encoder_pointer){ + return 4 * EncoderReg.wrappers.get(encoder_pointer).getValue(); + } + + public static double getEncoderPeriod(long encoder_pointer){ + return 1 / EncoderReg.wrappers.get(encoder_pointer).getRate(); + } + + public static void setEncoderMaxPeriod(long encoder_pointer, double maxPeriod){ + } + + public static boolean getEncoderStopped(long encoder_pointer){ + return false; + } + + public static boolean getEncoderDirection(long encoder_pointer){ + return false; + } + + public static void setEncoderReverseDirection(long encoder_pointer, + boolean reverseDirection){ + } + + public static void setEncoderSamplesToAverage(long encoder_pointer, + int samplesToAverage){ + } + + public static int getEncoderSamplesToAverage(long encoder_pointer){ + return 0; + } + + public static void setEncoderIndexSource(long digital_port, int pin, + boolean analogTrigger, boolean activeHigh, boolean edgeSensitive){ + } + +} diff --git a/src/main/java/jaci/openrio/toast/core/loader/simulation/SimulationData.java b/src/main/java/jaci/openrio/toast/core/loader/simulation/SimulationData.java index 527a7d6..7cf3b5e 100644 --- a/src/main/java/jaci/openrio/toast/core/loader/simulation/SimulationData.java +++ b/src/main/java/jaci/openrio/toast/core/loader/simulation/SimulationData.java @@ -26,6 +26,11 @@ public class SimulationData { */ public static byte[] dioValues = new byte[10]; public static byte[] dioDirections = new byte[10]; + + /** + * ANALOG INPUT * + */ + public static short[] analogValues = new short[4]; /** * Set the Digital IO on the given port with the given value diff --git a/src/main/java/jaci/openrio/toast/core/loader/simulation/SimulationGUI.java b/src/main/java/jaci/openrio/toast/core/loader/simulation/SimulationGUI.java index d15591c..961d09f 100644 --- a/src/main/java/jaci/openrio/toast/core/loader/simulation/SimulationGUI.java +++ b/src/main/java/jaci/openrio/toast/core/loader/simulation/SimulationGUI.java @@ -1,17 +1,28 @@ package jaci.openrio.toast.core.loader.simulation; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; + import jaci.openrio.toast.core.Toast; +import jaci.openrio.toast.core.loader.simulation.encoder.EncoderGUI; import jaci.openrio.toast.core.loader.simulation.jni.InterruptContainer; import jaci.openrio.toast.core.loader.simulation.srx.TalonSRX_GUI; import jaci.openrio.toast.lib.profiler.Profiler; import jaci.openrio.toast.lib.state.RobotState; -import javax.imageio.ImageIO; -import javax.swing.*; -import java.awt.*; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - /** * This is the Rat's nest of code that is the Simulation GUI. There is no clean way to programmatically create a GUI * with Swing. Most of the code called in this class is only called once, at runtime. This class is mostly self-contained @@ -173,7 +184,7 @@ public void callback(double value) { } }); } - + createLabel("Power", 210, 10, 100, 14, new Color(180, 180, 180)); GuiNumberSpinner voltage = new GuiNumberSpinner(205, 30, 12.5, 0.1, 5, 12.8, true, this); @@ -236,6 +247,34 @@ public void onClick() { } public void onToggle(boolean state) { } }); + + GuiButton encoderButton = new GuiButton(20, 180, 100, 30, false, "Encoders", false, this); + encoderButton.setCallback(new GuiButton.ButtonCallback() { + + /* (non-Javadoc) + * @see jaci.openrio.toast.core.loader.simulation.GuiButton.ButtonCallback#onToggle(boolean) + */ + public void onToggle(boolean state) { + } + + /* (non-Javadoc) + * @see jaci.openrio.toast.core.loader.simulation.GuiButton.ButtonCallback#onClick() + */ + @Override + public void onClick() { + openEncoder(); + } + }); + + // GuiNumberSpinners for controlling analog input + GuiNumberSpinner analog0 = new GuiNumberSpinner(355, 470, 0, 1, -10, 10, true, this); + analog0.setCallback(value -> SimulationData.analogValues[0] = (short) value); + GuiNumberSpinner analog1 = new GuiNumberSpinner(380, 485, 0, 1, -10, 10, true, this); + analog1.setCallback(value -> SimulationData.analogValues[1] = (short) value); + GuiNumberSpinner analog2 = new GuiNumberSpinner(410, 470, 0, 1, -10, 10, true, this); + analog2.setCallback(value -> SimulationData.analogValues[2] = (short) value); + GuiNumberSpinner analog3 = new GuiNumberSpinner(435, 485, 0, 1, -10, 10, true, this); + analog3.setCallback(value -> SimulationData.analogValues[3] = (short) value); } /** @@ -253,6 +292,14 @@ public void openPneumatics() { if (PneumaticsGUI.INSTANCE == null) PneumaticsGUI.create(); } + + /** + * Open the Encoder GUI + */ + public void openEncoder(){ + if (EncoderGUI.INSTANCE == null) + EncoderGUI.create(); + } /** * Create a JLabel to place next to various components. diff --git a/src/main/java/jaci/openrio/toast/core/loader/simulation/encoder/EncoderGUI.java b/src/main/java/jaci/openrio/toast/core/loader/simulation/encoder/EncoderGUI.java new file mode 100644 index 0000000..624e2dd --- /dev/null +++ b/src/main/java/jaci/openrio/toast/core/loader/simulation/encoder/EncoderGUI.java @@ -0,0 +1,127 @@ +package jaci.openrio.toast.core.loader.simulation.encoder; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import jaci.openrio.toast.core.loader.simulation.GuiNumberSpinner; +import jaci.openrio.toast.core.loader.simulation.GuiNumberSpinner.Callback; + +/** + * Panel for simulated encoders + * + * @author LoadingPleaseWait + */ +public class EncoderGUI extends JPanel { + + private static final long serialVersionUID = -5795176560686508623L; + + public static EncoderGUI INSTANCE; + + /** + * @return EncoderGUI instance + */ + public static JPanel create() { + JFrame frame = new JFrame("Toast Encoder GUI"); + JPanel panel = new EncoderGUI(); + frame.add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setPreferredSize(new Dimension(400, 375)); + frame.setVisible(true); + frame.setResizable(true); + frame.addWindowListener(new WindowAdapter() { + /* (non-Javadoc) + * @see java.awt.event.WindowAdapter#windowOpened(java.awt.event.WindowEvent) + */ + @Override + public void windowOpened(WindowEvent event) { + super.windowOpened(event); + } + + /* (non-Javadoc) + * @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent) + */ + @Override + public void windowClosing(WindowEvent event) { + super.windowClosing(event); + INSTANCE = null; + } + }); + + return panel; + } + + /** + * Set up the JPanel + */ + public EncoderGUI(){ + INSTANCE = this; + + this.setBackground(new Color(11, 11, 11)); + this.setPreferredSize(new Dimension(400, 375)); + this.setVisible(true); + this.setLayout(null); + + initElements(); + } + + /** + * Remove everything and then add everything back + */ + public void reinitElements(){ + removeAll(); + initElements(); + } + + /** + * Initialize elements in the panel + */ + public void initElements(){ + // labels and number spinners for each encoder + for(Long key : EncoderReg.wrappers.keySet()){ + JLabel encoderLabel = new JLabel("Encoder " + key); + encoderLabel.setForeground(Color.WHITE);// white text + encoderLabel.setBounds(10, key.intValue() * 20 + 10, 100, 20); + add(encoderLabel); + // encoder value + JLabel countLabel = new JLabel("Count"); + countLabel.setForeground(Color.WHITE); + countLabel.setBounds(120, key.intValue() * 20 + 10, 100, 20); + add(countLabel); + GuiNumberSpinner countSpinner = new GuiNumberSpinner(170, key.intValue() * 20 + 15, 0, 1, -10, 10, true, this); + countSpinner.setCallback(new Callback() { + + /* (non-Javadoc) + * @see jaci.openrio.toast.core.loader.simulation.GuiNumberSpinner.Callback#callback(double) + */ + @Override + public void callback(double value) { + EncoderReg.wrappers.get(key).setValue((int) value); + } + }); + // encoder rate + JLabel rateLabel = new JLabel("Rate"); + rateLabel.setForeground(Color.WHITE); + rateLabel.setBounds(260, key.intValue() * 20 + 10, 100, 20); + add(rateLabel); + GuiNumberSpinner rateSpinner = new GuiNumberSpinner(300, key.intValue() * 20 + 15, 1, 0.1, -5, 5, true, this); + rateSpinner.setCallback(new Callback() { + + /* (non-Javadoc) + * @see jaci.openrio.toast.core.loader.simulation.GuiNumberSpinner.Callback#callback(double) + */ + @Override + public void callback(double value) { + EncoderReg.wrappers.get(key).setRate(value); + } + }); + } + } + +} diff --git a/src/main/java/jaci/openrio/toast/core/loader/simulation/encoder/EncoderReg.java b/src/main/java/jaci/openrio/toast/core/loader/simulation/encoder/EncoderReg.java new file mode 100644 index 0000000..8fce192 --- /dev/null +++ b/src/main/java/jaci/openrio/toast/core/loader/simulation/encoder/EncoderReg.java @@ -0,0 +1,52 @@ +package jaci.openrio.toast.core.loader.simulation.encoder; + +import java.util.HashMap; + +/** + * Registry for simulated encoders + * + * @author LoadingPleaseWait + */ +public class EncoderReg { + + public static HashMap wrappers = new HashMap<>(); + + /** + * Wrapper for simulated encoders to be put in the EncoderRegistry + */ + public static class EncoderWrapper{ + + private int value; + private double rate; + + /** + * @return the value + */ + public int getValue() { + return value; + } + + /** + * @param value the value to set + */ + public void setValue(int value) { + this.value = value; + } + + /** + * @return the rate + */ + public double getRate() { + return rate; + } + + /** + * @param rate the rate to set + */ + public void setRate(double rate) { + this.rate = rate; + } + + } + +} diff --git a/src/main/resources/assets/toast/patches/patches.txt b/src/main/resources/assets/toast/patches/patches.txt index 6d739c8..99a79df 100644 --- a/src/main/resources/assets/toast/patches/patches.txt +++ b/src/main/resources/assets/toast/patches/patches.txt @@ -8,6 +8,7 @@ edu/wpi/first/wpilibj/communication/FRCNetworkCommunicationsLibrary.sim edu/wpi/first/wpilibj/hal/AccelerometerJNI.sim edu/wpi/first/wpilibj/hal/AnalogJNI.sim edu/wpi/first/wpilibj/hal/DIOJNI.sim +edu/wpi/first/wpilibj/hal/EncoderJNI.sim edu/wpi/first/wpilibj/hal/HALUtil.sim edu/wpi/first/wpilibj/hal/InterruptJNI$InterruptJNIHandlerFunction.sim edu/wpi/first/wpilibj/hal/InterruptJNI.sim @@ -19,4 +20,4 @@ edu/wpi/first/wpilibj/hal/RelayJNI.sim edu/wpi/first/wpilibj/hal/SolenoidJNI.sim edu/wpi/first/wpilibj/hal/CanTalonJNI.sim edu/wpi/first/wpilibj/hal/DigitalGlitchFilterJNI.sim -edu/wpi/first/wpilibj/hal/NotifierJNI.sim \ No newline at end of file +edu/wpi/first/wpilibj/hal/NotifierJNI.sim