/* * Copyright 2015-2016 Cel Skeggs * * This file is part of the CCRE, the Common Chicken Runtime Engine. * * The CCRE is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * The CCRE is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with the CCRE. If not, see <http://www.gnu.org/licenses/>. * * * This file contains code inspired by/based on code Copyright 2008-2014 FIRST. * To see the license terms of that code (modified BSD), see the root of the CCRE. */ package ccre.frc; import java.nio.ByteBuffer; import ccre.concurrency.ReporterThread; import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary; import edu.wpi.first.wpilibj.hal.HALUtil; class DirectDriverStation { public static final int JOYSTICK_NUM = 6; public static final int AXIS_NUM = FRCNetworkCommunicationsLibrary.kMaxJoystickAxes; public static final int POV_NUM = FRCNetworkCommunicationsLibrary.kMaxJoystickPOVs; public static final int[] buttons = new int[JOYSTICK_NUM]; public static final int[] buttonCounts = new int[JOYSTICK_NUM]; public static final short[][] axes = new short[JOYSTICK_NUM][]; public static final short[][] povs = new short[JOYSTICK_NUM][]; public static void init() { ReporterThread comm = new ReporterThread("DriverStationCommunication") { @Override protected void threadBody() throws Throwable { mainloop(); } }; comm.setPriority((Thread.NORM_PRIORITY + Thread.MAX_PRIORITY) / 2); comm.start(); } private static boolean dataUpdated = false; private static final Object updateLock = new Object(); private static void mainloop() { long dataMutex = HALUtil.initializeMutexNormal(); long dataSemaphore = HALUtil.initializeMultiWait(); FRCNetworkCommunicationsLibrary.setNewDataSem(dataSemaphore); while (true) { HALUtil.takeMultiWait(dataSemaphore, dataMutex); for (int stick = 0; stick < JOYSTICK_NUM; stick++) { axes[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickAxes((byte) stick); povs[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickPOVs((byte) stick); ByteBuffer countBuffer = ByteBuffer.allocateDirect(1); buttons[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickButtons((byte) stick, countBuffer); buttonCounts[stick] = countBuffer.get(); } synchronized (updateLock) { dataUpdated = true; updateLock.notifyAll(); } } } public static boolean isNewControlData() { if (dataUpdated) { dataUpdated = false; return true; } else { return false; } } public static void waitForData() throws InterruptedException { synchronized (updateLock) { while (!dataUpdated) { updateLock.wait(); } } } public static float getStickAxis(int joy, int axis) { if (joy < 0 || joy >= JOYSTICK_NUM) { throw new RuntimeException("Invalid joystick port: " + joy); } if (axis < 0 || axis >= AXIS_NUM) { throw new RuntimeException("Invalid joystick axis: " + axis); } short[] jaxes = axes[joy]; if (jaxes == null || axis >= jaxes.length) { return 0; } short value = jaxes[axis]; if (value < 0) { return value / 128f; } else { return value / 127f; } } public static boolean getStickButton(int joy, int button) { if (joy < 0 || joy >= JOYSTICK_NUM) { throw new RuntimeException("Invalid joystick port: " + joy); } if (button < 0) { throw new RuntimeException("Invalid joystick button ID: " + button); } if (button >= buttonCounts[joy]) { return false; } else { return (buttons[joy] & (1 << button)) != 0; } } public static int getStickPOV(int joy, int pov) { if (joy < 0 || joy >= JOYSTICK_NUM) { throw new RuntimeException("Invalid joystick port: " + joy); } if (pov < 0 || pov >= POV_NUM) { throw new RuntimeException("Invalid joystick POV: " + pov); } short[] jpovs = povs[joy]; if (jpovs == null || pov >= jpovs.length) { return -1; } return jpovs[pov]; } public static void verifyPortNumber(int joy) { if (joy < 0 || joy >= JOYSTICK_NUM) { throw new RuntimeException("Invalid joystick port: " + joy); } } public static void setStickRumble(int joy, float leftRumble, float rightRumble) { FRCNetworkCommunicationsLibrary.HALSetJoystickOutputs((byte) joy, 0, (short) Math.max(0, Math.min(65535, (int) (65535 * leftRumble))), (short) Math.max(0, Math.min(65535, (int) (65535 * rightRumble)))); } }