Squashed 'third_party/allwpilib_2016/' content from commit 7f61816
Change-Id: If9d9245880859cdf580f5d7f77045135d0521ce7
git-subtree-dir: third_party/allwpilib_2016
git-subtree-split: 7f618166ed253a24629934fcf89c3decb0528a3b
diff --git a/simulation/SimDS/build.gradle b/simulation/SimDS/build.gradle
new file mode 100644
index 0000000..0acaaee
--- /dev/null
+++ b/simulation/SimDS/build.gradle
@@ -0,0 +1,54 @@
+apply plugin: 'java'
+apply plugin: 'application'
+apply plugin: 'com.github.johnrengelman.shadow'
+apply plugin: 'maven-publish'
+
+// Adds the dependency for the shadow plugin, which creates an uberjar with all dependencies
+buildscript {
+ repositories { jcenter() }
+ dependencies {
+ classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.1'
+ }
+}
+
+publishing {
+ publications {
+ maven(MavenPublication) {
+ artifact(shadowJar) {
+ // The shadow plugin has the 'all' classifier. We don't want this, so use null instead
+ classifier null
+ }
+ artifact(simDsSources) {
+ classifier 'sources'
+ }
+ artifact(simDsJavadoc) {
+ classifier 'javadoc'
+ }
+ groupId 'edu.wpi.first.wpilibj.simulation'
+ artifactId 'SimDS'
+ version '0.1.0-SNAPSHOT'
+ }
+ }
+ setupWpilibRepo(it)
+}
+
+mainClassName = 'edu.wpi.first.wpilibj.simulation.ds.Main'
+
+dependencies {
+ compile 'net.java.jinput:jinput:2.0.5'
+ compile project(':simulation:JavaGazebo')
+}
+
+task simDsSources(type: Jar, dependsOn: classes) {
+ description = 'Creates the sources jar for the SimDS'
+ group = 'WPILib'
+ classifier = 'sources'
+ from sourceSets.main.allJava
+}
+
+task simDsJavadoc(type: Jar, dependsOn: javadoc) {
+ description = 'Creates the javadoc jar for the SimDS'
+ group = 'WPILib'
+ classifier = 'javadoc'
+ from javadoc.destinationDir
+}
\ No newline at end of file
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/DS.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/DS.java
new file mode 100644
index 0000000..bd12c41
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/DS.java
@@ -0,0 +1,152 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.DropMode;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+
+import org.gazebosim.transport.Node;
+import org.gazebosim.transport.Publisher;
+
+import edu.wpi.first.wpilibj.simulation.ds.FakeJoystick;
+import edu.wpi.first.wpilibj.simulation.ds.ISimJoystick;
+import edu.wpi.first.wpilibj.simulation.ds.JoystickProvider;
+import gazebo.msgs.GzDriverStation.DriverStation;
+
+public class DS {
+ private JoystickProvider joystickProvider;
+ private JoystickList joysticks;
+
+ private JFrame mainframe;
+ private JPanel modePanel;
+ private ActionListener modeListener;
+ private ButtonGroup modes;
+ private JButton enable, refresh;
+
+ public enum State {
+ Disabled, Teleop, Autonomous, Test;
+ }
+ private boolean enabled = false;
+ private State state = State.Teleop;
+ private DriverStation.State protoState = DriverStation.State.TELEOP;
+ private Publisher<DriverStation> pub;
+
+ public DS(JoystickProvider joystickProvider) {
+ this.joystickProvider = joystickProvider;
+ mainframe = new JFrame();
+ mainframe.setTitle("FRC Simulation DriverStation");
+ mainframe.setLayout(new GridBagLayout());
+ GridBagConstraints constraints = new GridBagConstraints();
+
+ makeModeButtons(constraints);
+ mainframe.pack();
+ constraints.gridy = 1;
+ makeEnableButton(constraints);
+
+ constraints.gridx = 1;
+ constraints.gridy = 0;
+ makeJoystickUI(constraints);
+ mainframe.pack();
+ constraints.gridy = 1;
+ makeRefreshButton(constraints);
+
+ mainframe.pack();
+ mainframe.setVisible(true);
+ }
+
+ private void makeModeButtons(GridBagConstraints constraints) {
+ modePanel = new JPanel();
+ modePanel.setLayout(new BoxLayout(modePanel, BoxLayout.PAGE_AXIS));
+
+ modeListener = new ModeAction(this);
+ JRadioButton teleop = new JRadioButton("Teleop");
+ teleop.setActionCommand(State.Teleop.toString());
+ teleop.addActionListener(modeListener);
+ JRadioButton auto = new JRadioButton("Autonomous");
+ auto.setActionCommand(State.Autonomous.toString());
+ auto.addActionListener(modeListener);
+ JRadioButton test = new JRadioButton("Test");
+ test.setActionCommand(State.Test.toString());
+ test.addActionListener(modeListener);
+ teleop.setSelected(true);
+
+ modes = new ButtonGroup();
+ modes.add(teleop);
+ modes.add(auto);
+ modes.add(test);
+ modePanel.add(teleop);
+ modePanel.add(auto);
+ modePanel.add(test);
+ mainframe.add(modePanel, constraints);
+ }
+
+ private void makeEnableButton(GridBagConstraints constraints) {
+ enable = new JButton("Enable");
+ enable.addActionListener(new EnableAction(this));
+ enable.setPreferredSize(new Dimension(modePanel.getSize().width, 50));
+ mainframe.add(enable, constraints);
+ }
+
+ private void makeJoystickUI(GridBagConstraints constraints) {
+ joysticks = new JoystickList(joystickProvider);
+ mainframe.add(joysticks, constraints);
+ scanForJoysticks();
+ }
+
+ public void scanForJoysticks() {
+ joysticks.removeAll();
+ List<ISimJoystick> sticks = joystickProvider.scanForJoysticks();
+ while (sticks.size() < 6) {
+ sticks.add(new FakeJoystick());
+ }
+ joysticks.setListData(sticks);
+ }
+
+ private void makeRefreshButton(GridBagConstraints constraints) {
+ refresh = new JButton("Refresh Joysticks");
+ refresh.addActionListener(new RefreshAction(this));
+ refresh.setPreferredSize(new Dimension(joysticks.getSize().width, 50));
+ mainframe.add(refresh, constraints);
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ enable.setText(enabled ? "Disable" : "Enable");
+ }
+
+ public State getState() {
+ return enabled ? state : State.Disabled;
+ }
+
+ public void setState(State state) {
+ setEnabled(false);
+ this.state = state;
+ switch (state) {
+ case Autonomous: protoState = DriverStation.State.AUTO; break;
+ case Teleop: protoState = DriverStation.State.TELEOP; break;
+ case Test: protoState = DriverStation.State.TEST; break;
+ default: break;
+ }
+ }
+
+ public void toggleEnable() {
+ setEnabled(!enabled);
+ }
+
+ public void advertise(Node node) {
+ pub = node.advertise("ds/state", DriverStation.getDefaultInstance());
+ }
+
+ public void publish() {
+ pub.publish(DriverStation.newBuilder().setEnabled(enabled).setState(protoState).build());
+ }
+}
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/EnableAction.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/EnableAction.java
new file mode 100644
index 0000000..f847568
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/EnableAction.java
@@ -0,0 +1,18 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class EnableAction implements ActionListener {
+ private DS ds;
+
+ public EnableAction(DS ds) {
+ this.ds = ds;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ ds.toggleEnable();
+ }
+
+}
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/FakeJoystick.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/FakeJoystick.java
new file mode 100644
index 0000000..4831a27
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/FakeJoystick.java
@@ -0,0 +1,19 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import org.gazebosim.transport.Node;
+
+
+public class FakeJoystick implements ISimJoystick {
+
+ public String getName() {
+ return "Empty Joystick";
+ }
+
+ public String toString() {
+ return getName();
+ }
+
+ @Override public void advertise(Node node, int i) {}
+
+ @Override public void publish() {}
+}
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/ISimJoystick.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/ISimJoystick.java
new file mode 100644
index 0000000..9263a1b
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/ISimJoystick.java
@@ -0,0 +1,9 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import org.gazebosim.transport.Node;
+
+public interface ISimJoystick {
+ String getName();
+ void advertise(Node node, int i);
+ void publish();
+}
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/JoystickList.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/JoystickList.java
new file mode 100644
index 0000000..f598a3d
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/JoystickList.java
@@ -0,0 +1,118 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DragSourceDragEvent;
+import java.awt.dnd.DragSourceDropEvent;
+import java.awt.dnd.DragSourceEvent;
+import java.awt.dnd.DragSourceListener;
+import java.util.List;
+
+import javax.swing.DropMode;
+import javax.swing.JList;
+import javax.swing.TransferHandler;
+
+import edu.wpi.first.wpilibj.simulation.ds.ISimJoystick;
+import edu.wpi.first.wpilibj.simulation.ds.JoystickProvider;
+
+@SuppressWarnings("serial")
+public class JoystickList extends JList<ISimJoystick> {
+ private JoystickProvider joystickProvider;
+ List<ISimJoystick> joysticks;
+
+ public JoystickList(JoystickProvider joystickProvider) {
+ super();
+ this.joystickProvider = joystickProvider;
+
+ setDragEnabled(true);
+ setDropMode(DropMode.INSERT);
+
+ setTransferHandler(new DropHandler(this));
+ new DragListener(this);
+ }
+
+ public void moveElement(int index, int dropTargetIndex) {
+ ISimJoystick move = joysticks.get(index);
+ joysticks.add(dropTargetIndex, move);
+ joysticks.remove(index < dropTargetIndex ? index : index + 1);
+ setListData(joysticks);
+ }
+
+ public void setListData(List<ISimJoystick> sticks) {
+ joysticks = sticks;
+ setListData(sticks.toArray(new ISimJoystick[0]));
+ joystickProvider.setJoysticks(sticks);
+ }
+
+ class DragListener implements DragSourceListener, DragGestureListener {
+ JoystickList list;
+
+ DragSource ds = new DragSource();
+
+ public DragListener(JoystickList list) {
+ this.list = list;
+ ds.createDefaultDragGestureRecognizer(
+ list, DnDConstants.ACTION_MOVE, this);
+ }
+
+ public void dragGestureRecognized(DragGestureEvent dge) {
+ StringSelection transferable = new StringSelection(
+ Integer.toString(list.getSelectedIndex()));
+ ds.startDrag(dge, DragSource.DefaultCopyDrop, transferable, this);
+ }
+
+ public void dragEnter(DragSourceDragEvent dsde) {}
+ public void dragExit(DragSourceEvent dse) {}
+ public void dragOver(DragSourceDragEvent dsde) {}
+ public void dragDropEnd(DragSourceDropEvent dsde) {}
+ public void dropActionChanged(DragSourceDragEvent dsde) {}
+ }
+
+ class DropHandler extends TransferHandler {
+ JoystickList list;
+
+ public DropHandler(JoystickList list) {
+ this.list = list;
+ }
+
+ public boolean canImport(TransferHandler.TransferSupport support) {
+ if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
+ return false;
+ }
+ JList.DropLocation dl = (JList.DropLocation) support
+ .getDropLocation();
+ if (dl.getIndex() == -1) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public boolean importData(TransferHandler.TransferSupport support) {
+ if (!canImport(support)) {
+ return false;
+ }
+
+ Transferable transferable = support.getTransferable();
+ String indexString;
+ try {
+ indexString = (String) transferable.getTransferData(DataFlavor.stringFlavor);
+ } catch (Exception e) {
+ return false;
+ }
+
+ int index = Integer.parseInt(indexString);
+ JList.DropLocation dl = (JList.DropLocation) support.getDropLocation();
+ int dropTargetIndex = dl.getIndex();
+
+ list.moveElement(index, dropTargetIndex);
+
+ return true;
+ }
+ }
+}
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/JoystickProvider.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/JoystickProvider.java
new file mode 100644
index 0000000..4c22320
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/JoystickProvider.java
@@ -0,0 +1,44 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.wpi.first.wpilibj.simulation.ds.ISimJoystick;
+import edu.wpi.first.wpilibj.simulation.ds.SimJoystick;
+
+import net.java.games.input.Controller;
+import net.java.games.input.ControllerEnvironment;
+
+public class JoystickProvider {
+ List<ISimJoystick> joysticks;
+
+ public JoystickProvider() {
+ scanForJoysticks();
+ }
+
+ public List<ISimJoystick> scanForJoysticks() {
+ List<ISimJoystick> foundControllers = new ArrayList<>();
+ Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();
+
+ for(int i = 0; i < controllers.length; i++){
+ Controller controller = controllers[i];
+ if (controller.getType() == Controller.Type.STICK
+ || controller.getType() == Controller.Type.GAMEPAD
+ || controller.getType() == Controller.Type.WHEEL
+ || controller.getType() == Controller.Type.FINGERSTICK) {
+ foundControllers.add(new SimJoystick(controller));
+ }
+ }
+
+ joysticks = foundControllers;
+ return foundControllers;
+ }
+
+ public List<ISimJoystick> getJoysticks() {
+ return joysticks;
+ }
+
+ public void setJoysticks(List<ISimJoystick> joysticks) {
+ this.joysticks = joysticks;
+ }
+}
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/Main.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/Main.java
new file mode 100644
index 0000000..2f5188a
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/Main.java
@@ -0,0 +1,61 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import gazebo.msgs.GzFloat64.Float64;
+
+import org.gazebosim.transport.Msgs;
+import org.gazebosim.transport.Node;
+import org.gazebosim.transport.Subscriber;
+import org.gazebosim.transport.SubscriberCallback;
+
+public class Main {
+ private static double simTime = 0;
+ private static Subscriber<Float64> sub;
+
+ public static void main(String args[]) {
+ Node node = new Node("frc");
+ try {
+ node.waitForConnection();
+ } catch (Throwable thr) {
+ System.err.println("Could not connect to Gazebo.");
+ thr.printStackTrace();
+ System.exit(1);
+ return;
+ }
+
+ JoystickProvider provider = new JoystickProvider();
+ DS ds = new DS(provider);
+ ds.advertise(node);
+
+ sub = node.subscribe("time", Msgs.Float64(),
+ new SubscriberCallback<Float64>() {
+ @Override
+ public void callback(Float64 msg) {
+ simTime = msg.getData();
+ synchronized(sub) {
+ sub.notifyAll();
+ }
+ }
+ }
+ );
+
+ while (true) {
+ final double start = simTime;
+ for (int i = 0; i < provider.getJoysticks().size(); i++) {
+ ISimJoystick joystick = provider.getJoysticks().get(i);
+ joystick.advertise(node, i);
+ joystick.publish();
+ }
+ ds.publish();
+
+ while ((simTime - start) < 0.020 /*20ms*/) {
+ synchronized(sub) {
+ try {
+ sub.wait(); // Block until time progresses
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/ModeAction.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/ModeAction.java
new file mode 100644
index 0000000..532ef67
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/ModeAction.java
@@ -0,0 +1,18 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class ModeAction implements ActionListener {
+ private DS ds;
+
+ public ModeAction(DS ds) {
+ this.ds = ds;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ ds.setState(DS.State.valueOf(e.getActionCommand()));
+ }
+
+}
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/RefreshAction.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/RefreshAction.java
new file mode 100644
index 0000000..5f264e0
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/RefreshAction.java
@@ -0,0 +1,18 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class RefreshAction implements ActionListener {
+ private DS ds;
+
+ public RefreshAction(DS ds) {
+ this.ds = ds;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ ds.scanForJoysticks();
+ }
+
+}
diff --git a/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/SimJoystick.java b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/SimJoystick.java
new file mode 100644
index 0000000..23794ca
--- /dev/null
+++ b/simulation/SimDS/src/main/java/edu/wpi/first/wpilibj/simulation/ds/SimJoystick.java
@@ -0,0 +1,69 @@
+package edu.wpi.first.wpilibj.simulation.ds;
+
+import gazebo.msgs.GzJoystick.Joystick;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.gazebosim.transport.Node;
+import org.gazebosim.transport.Publisher;
+
+import net.java.games.input.Component;
+import net.java.games.input.Controller;
+
+public class SimJoystick implements ISimJoystick {
+ private Controller controller;
+ private List<Component> axes, buttons;
+ private Publisher<Joystick> pub = null;
+ private int prevI = -1; private Node prevNode = null;
+
+ public SimJoystick(Controller controller) {
+ this.controller = controller;
+ axes = new ArrayList<>();
+ buttons = new ArrayList<>();
+ for(Component c : controller.getComponents()) {
+ if (c.getIdentifier() instanceof Component.Identifier.Axis) {
+ axes.add(c);
+ } else if (c.getIdentifier() instanceof Component.Identifier.Button) {
+ buttons.add(c);
+ }
+ }
+ }
+
+ @Override
+ public String getName() {
+ return controller.getName();
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+
+ @Override
+ public void advertise(Node node, int i) {
+ if (pub == null) {
+ // I'm good
+ } else if (prevI != i || prevNode != node) {
+ // TODO: pub.close();
+ } else {
+ return; // No change
+ }
+ pub = node.advertise("ds/joysticks/"+i, Joystick.getDefaultInstance());
+ prevNode = node;
+ prevI = i;
+ }
+
+ @Override
+ public void publish() {
+ controller.poll();
+ Joystick.Builder builder = Joystick.newBuilder();
+ for (Component a : axes) {
+ builder.addAxes(a.getPollData());
+ }
+ for (Component b : buttons) {
+ builder.addButtons(b.getPollData() > 0.5);
+ }
+ pub.publish(builder.build());
+ }
+}